はじめに
共通鍵暗号のAESを使う方法を調べていたときに気になった、暗号利用モードのパディング要否の基準について説明します。
AESを使うとき、AESが一度に暗号化できる平文の長さは128ビットなので、それより長い平文は128ビットごとのブロックに分ける必要があります。
ブロックに分けて暗号化するやり方はいくつかあり、暗号利用モードと呼ばれています。
暗号利用モードには、例えばCBCモードやCTRモードなどがあります。CBCモードはパディングが必要で、CTRモードは不要です。
もともと、なんとなく暗号利用モードは全てパディングが必要だと思っていました。しかし、そうではないと知り、必要か必要でないかの基準はなんなのか調べてみました。
結論
ストリーム暗号(後ほど説明します)として使える暗号利用モードはパディングが不要です。
言い換えると、以下の条件を満たす暗号利用モードは平文のパディングが必要だと認識しています。
条件: 特定のブロックを暗号化する際に、暗号化を適用する対象がそのブロックの平文(またはそのブロックの平文からなんらかの方法で生成された文字列)である場合。
暗号利用モードとは
上でも触れましたが、AESなどの暗号方式は一度に暗号化する平文の長さが決まっています(AESは128ビット)。
その長さをブロック長と言います。
ブロック長よりも長い平文を暗号化するには、そのブロック長のブロックに分割して、それぞれのブロックに暗号化を適用します。
適用するやり方がいくつかあり、そのやり方を暗号利用モードといいます。
暗号利用モード(あんごうりようモード、Block cipher modes of operation)とは、ブロック暗号を利用して、ブロック長よりも長いメッセージを暗号化するメカニズムのことである。
Wikipedia | 暗号利用モード
ここでは、CBCモードとCTRモードについて説明します。他のモードについては、上記のリンクをご参照ください。
CBCモード(Cipher Block Chaining Mode)とは
そのブロックの平文と前のブロックの結果をXORしたものに、暗号化を適用する方法です。
一番最初のブロックには、前のブロックの結果はないので、初期化ベクトル(initialization vector, iv)を渡します。
AESを使う時によく見かける暗号利用モードです。
↓CBCモードの図(上記のWikipediaのページから拝借しました)
CTRモード(Counter Mode)とは
ブロック長と同じ長さの「Nonce + カウンター」を暗号化し、その暗号化結果とそのブロックの平文をXORします。
Nonceは暗号化するたびにランダムな文字列として生成する必要があります。
カウンターは、00000001, 00000002, ...のような文字列です。何番目のブロックであるかを表す数字です。
↓CBCモードの図(上記のWikipediaのページから拝借しました)
パディングとは
AESのような暗号方式は、固定長の文字列を暗号化します(AESは128ビット)。この長さをブロック長と言います。
暗号利用モードを使い平文をいくつかのブロックに分けることで、ブロック長より長い平文を暗号化できます。
ただ必ずしも、平文はブロック長の倍数になるとは限りません(AESなら128の倍数になるとは限りません)。
平文の長さが、ブロック長の倍数になるまで(AESなら128の倍数になるまで)、データを埋める処理がパディングです。
CBCモードはパディングが必要
例えば、CBCモードでAESを使う場合、前のブロックの結果とそのブロックの平文をXORしたものがそのブロックの暗号化対象です。このブロックの暗号化対象は128ビットである必要があります。ということはこのブロックの平文は128ビットである必要があり、平文全体の長さは128の倍数である必要があります。そのためパディングが必要です。
CTRモードのようなストリーム暗号は、パディング不要
一方で、CTRモードは、パディングが不要です。
これは、そのブロックで暗号化を適用する対象が、そのブロックの平文ではなくNonceとカウンターを連結した文字列だからです。
ブロック長と同じ長さである(AESなら128ビットである)必要があるのは、そのブロックの平文ではなくNonceとカウンターを連結した文字列だからです。
CTRモードでは、Nonceとカウンターを連結した文字列に暗号化を適用したもの(これをAとします)とそのブロックの平文をXORした結果がそのブロックの結果です。
そのブロックの平文が、128ビットに満たない例えば1ビットの場合、Aの先頭1ビットとXORをとって、そのブロックの結果にします。
このように、そのブロックの平文が128ビットに満たなくても暗号化できるため、平文全体へのパディングは不要です。
言い換えると、以下の通りストリーム暗号として使える暗号利用モードはパディングが不要です。
パディングアルゴリズム:暗号化対象データ長がブロックサイズの整数倍となるように末尾にパディングを追加するアルゴリズムを指定します。AES の場合は PKCS#7 パディング方式がよく利用されます。ストリーム暗号に対応している場合は不要です。
https://www.tohoho-web.com/ex/crypt.html
ストリーム暗号は以下の通り、ブロック長ごとに暗号化するのではなく、1ビットごとに暗号化できる方法です。
ストリーム暗号(ストリームあんごう、stream cipher)とは、平文をビット単位あるいはバイト単位などで逐次、暗号化する暗号である。平文を64ビットや128ビットなどの固定長のブロックに分割して暗号化する暗号を指すブロック暗号に対比した語である。その構成上、入力がファイルではなくストリーム等の逐次追加されるデータであった場合、ブロック暗号は入力がブロックサイズに達するまで溜まらないと処理を進めることができないのに対し、ストリーム暗号はその必要がないのが特徴である。https://ja.m.wikipedia.org/wiki/%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E6%9A%97%E5%8F%B7
CTRモードを使う場合、そのブロックの平文がブロック長に満たないNビット場合でも、「Nonce + カウンター」を暗号化した結果の先頭のNビットとXORをとることで結果を出せるため、パディングがいらないのです。
終わりに
まとめると、ストリーム暗号として使える暗号利用モードでは、平文全体にパディングする必要はありません。
コメント