체크섬(checksum) 계산법

반응형


체크섬(checksum)

[정의]

체크섬(checksum)은 중복 검사의 한 형태로, 오류 정정을 통해, 공간(전자 통신)이나 시간(기억 장치) 속에서 송신된 자료의 무결성을 보호하는 단순한 방법이다.

통신에서 순환 중복 검사(CRC)를 체크섬이라고 말하기도 한다. 엄밀히 말하면 체크섬은 나열된 데이터를 더하여 체크섬 숫자를 얻고, 정해진 비트수의 모듈라로 정해진 비트수로 재구성 한다.


1) IP

[계산 방법]

패킷 전송 시 체크섬은 제일 마지막에 계산되는데 그 때 체크섬의 값은 0으로 초기화가 되어있어야 한다. 쉬운 계산을 위해 10진수로 진행한다.

  1. ip 헤더의 모든 필드를 더해준다.(version, length, service, total length, id, flag, offset, ttl, protocol type, 출발지 ip, 도착지 ip) 체크썸은 초기화되어 있는 값인 0이기 때문에 더해도 의미가 없다.
  2. 모두 더한 값이 16진수로 2byte가 넘어가면 초과한 올림수를 제거한다. 패킷에서 체크썸의 크기는 2byte를 넘지 못하기 때문. 예를들어, 선행 과정에서 모두 더한 값이 20D33(16진수)이 나왔을 경우, 초과한 2를 떼어 뒤에 더해준다. ex) 20D33 → 0D33 + 2 =0D35
  3. 1의 보수를 취해준다. 2진수의 값에서 0은 1, 1은 0으로 바꿔준다. ex) 0000 1101 0011 0101 → 1111 0010 1100 1010

[계산 예시]

>>> ip_header

b'E\x00\x00(\x00\x00\x00\x00@\x01\x00\x00\xc0\xa8\x03N\xc0\xa8\x03l'

>>> struct.unpack("!20B", ip_header)

(69, 0, 0, 40, 0, 0, 0, 0, 64, 1, 0, 0, 192, 168, 3, 78, 192, 168, 3, 108)

>>> struct.unpack("!10H", ip_header)

(17664, 40, 0, 0, 16385, 0, 49320, 846, 49320, 876)

>>> sum=0

>>> for x in struct.unpack('!10H', ip_header):

...   sum+=x

>>> sum

134451


10진수 : 134451

16진수 : 20D33

2진수  : 10 0000 1101 0011 0011


>>> chk = (sum >> 16) + (sum & 0xffff)    //올림수 제거

>>> chk = (chk ^ 0xffff)    //1의 보수



2) TCP/UDP


TCP와 UDP는 체크섬 계산하는 방법이 IP와 약간 다르다. IP의 경우 IP 헤더의 값을 모두 더한 뒤 체크섬 계산을 진행하지만, TCP와 UDP는 더하는 값이 IP와는 다르다.

ip헤더의 출발지 ip + ip헤더의 도착지 ip + zero byte(\x00) + ip헤더의 protocol type + tcp헤더 길이 + tcp헤더의 모든 필드


[계산 방법]

이후에 체크섬 계산하는 방법은 IP 체크섬 계산 방법과 같다.

  1. ip 헤더의 모든 필드를 더해준다.(출발지 포트, 도착지 포트, 시퀀스 넘버, 응답 넘버, 플래그, 윈도우 사이즈, urgent pointer)
  2. 모두 더한 값이 16진수로 2byte가 넘어가면 초과한 올림수를 제거한다.
  3. 1의 보수를 취해준다.



반응형
TAGS.

Comments