チェックサムとは
チェックサム(checksum/チェックサム)は、データの誤りや変化を検出するため、内容から計算して照合する短い値です。送信側がデータから値を計算して添え、受信側が同じ範囲を再計算して比較します。
主目的は通信路・記憶媒体・転送処理で起きた偶発的なビット反転、欠落、並びの変化を見つけることです。加算、一の補数合計、CRCなど用途別のアルゴリズムがあります。
チェックサムが一致しても、悪意ある変更がないことは保証しません。攻撃者がデータを変えた後にチェックサムも再計算できるため、真正性にはMACやデジタル署名が必要です。

代表的な誤り検出方式
バイトや語を足して一定幅へ畳みます。軽い一方、並べ替え等を見逃しやすい方式があります。
16ビット語を一の補数加算し、最後に反転します。IP・TCP・UDPで使われます。
多項式演算でバーストエラーを効率よく検出します。Ethernetやgzip等に現れます。
意図的衝突を見つけにくくしますが、鍵なしでは送信者認証になりません。
計算する範囲を仕様どおりそろえる
パケット全体、ペイロードだけ、擬似ヘッダーを含む範囲など、チェックサム対象はプロトコルごとに違います。チェックサムフィールド自身を0として計算する方式や、末尾情報へ置く方式もあります。
フィールド追加やパディング、VLANタグ、オフロード後の状態など、観測位置で対象バイトが変わります。パケットキャプチャー上で未完成チェックサムに見える場合はNICオフロードの時点も確認します。
インターネットチェックサムの考え方
インターネットチェックサムはデータを16ビット語列として一の補数加算し、桁あふれを下位へ回し、最後にビット反転します。受信側がチェックサムを含めて計算すると規定の全ビット1結果になるかで確認できます。
バイト数が奇数なら計算上0バイトを補いますが、そのパディングを送信データへ実際に追加するとは限りません。ネットワークバイト順と語境界を揃えます。
TCP・UDPでは擬似ヘッダーも含める
TCP・UDP チェックサムには転送区分だけでなく、送信元・宛先IPアドレス、プロトコル識別、長さ等の擬似ヘッダーを含めます。誤った宛先やプロトコルへ届いたデータも検出対象にするためです。
IPv4ヘッダーチェックサムはIPv4ヘッダーだけを保護し、ルーターがTTLを変えるたび再計算します。IPv6基数ヘッダーには同じヘッダーチェックサムがありません。層ごとの保護範囲を混同しません。
CRCはバーストエラー検出に強い
CRC(Cyclic Redundancy Check/サイクリック・リダンダンシー・チェック/巡回冗長検査)はビット列を多項式として割った余りを使います。生成多項式と初期値、反転、出力処理が同じCRC名でも変種で異なります。
gzipのCRC32は展開後データ、Ethernet FCSはフレームの所定範囲を対象にします。「CRC32」と値だけを渡さず引数一式と対象バイトを合意します。
暗号学的ハッシュとの違い
チェックサムは想定する偶発エラーパターンを低コストで見つける設計です。暗号学的ハッシュは、攻撃者が入力を選べる状況でも衝突や原像を見つけにくくする設計です。
ただし鍵なしハッシュも、攻撃者がデータとハッシュを両方置換できれば改ざん防止になりません。悪意ある変更を検出し送信者を確かめるにはHMACや署名を使います。
不一致時は壊れた場所まで分からない
一つのチェックサムが不一致なら対象範囲のどこかが違うと分かりますが、位置や正しい値を通常は特定できません。再送、左右反転から再取得、誤り訂正符号等で回復します。
大きなファイルをチャンク別に検査すれば壊れたチャンクを絞れます。全体ハッシュとチャンクチェックサムは役割が異なり、組み合わせて使えます。
チェックサムは定めたバイト範囲から短い検査値を再計算し、偶発的な変化を見つけます。アルゴリズム、ビット幅、バイト順、パディング、対象フィールドをそろえ、敵対的改ざんにはMACや署名を使います。
Internet checksumの16bit一の補数加算:RFC 1071/gzip CRC32の対象と配置:RFC 1952