私の質問は-出力暗号文の長さはどのように決定されるのですか?
出力の長さは、使用されている暗号のブロックサイズの倍数でなければならないことを漠然と知っています。しかし、それは次のことを意味しますか?
- 入力データの長さが暗号ブロックサイズの倍数の場合、出力の長さは入力の長さと同じになりますか?
- 入力データの長さが暗号ブロック サイズの倍数でない場合、出力の長さは入力の長さ + 1 つのブロック サイズになりますか?
ありがとう!
私の質問は-出力暗号文の長さはどのように決定されるのですか?
出力の長さは、使用されている暗号のブロックサイズの倍数でなければならないことを漠然と知っています。しかし、それは次のことを意味しますか?
ありがとう!
ロバートは、暗号モードとパディング、およびおそらくブロックモードに応じた暗号文のサイズに関して正しいです。
ストリーミング モード (CTR など) で暗号を使用する場合、暗号文のサイズは平文のサイズと同じになります。GCM などの認証モードを使用する場合は、少なくとも認証タグを使用してこれを増やす必要があります。また、パディングのオーバーヘッドを取り除くために暗号化テキスト スチール (CTS) で CBC モードを使用することもできますが、これは 2 ブロック以上でしか機能しません。
ここで、現時点で最も一般的に使用されているモードである CBC モードの PKCS#5/7 準拠のパディングを想定してみましょう。01
この場合、平文は少なくとも 1 つのパディング バイトでパディングされます (そうしないと、アンパディングでは、たとえば、単一の値のパディング バイトでパディングされた平文と、ブロック サイズで割り切れる - 値のあるバイトで終わる平文を区別できません01
)。これは、平文がすでにブロック アラインされている場合、ブロック全体が追加されることを意味します。
もちろん、平文がブロック整列されていない場合、PKCS#7 パディングは最後のブロックを埋めるだけで済みます。したがって、その場合は 1 からblock size
バイトが追加されます。したがって、計算は次のようになります。
L暗号文= (L平文/ Lブロック) * (Lブロック+ 1)
ここで、Lプレーンテキスト/ Lブロックは切り捨てられます (ほとんどのプログラミング言語で整数計算を行うときは通常どおり)。
ここで、ブロック サイズが常に 16 バイトの AES を想定します。
0 bytes -> 16 bytes
1 byte -> 16 bytes
2 bytes -> 16 bytes
...
15 bytes -> 16 bytes
16 bytes -> 32 bytes
17 bytes -> 32 bytes
...
標準化されていないパディングを使用する実装がかなりあることに注意してください。例としては、PHP の mcrypt ライブラリーがあります (おそらく、mcrypt を暗号化の悪習のベースとして使用できます)。これはゼロ パディングを使用するため00
、平文がブロック アラインされるまで値のバイトをパディングするだけです。その場合、結果のサイズは次のように計算できます。
L暗号文= (L平文/ Lブロック- 1) * (Lブロック+ 1)
標準化されていないゼロパディングを予期しない実装でこれを使用する場合、または平文が1つ以上の00
値のバイトで終わる可能性がある場合、明らかに問題が発生します。
最後の注意: 一部の言語 (JavaCipher
など) には、ブロック サイズを取得するメソッドと、暗号化の実装から結果の暗号文を取得するメソッドがあります。自分で実装を開始する前に、API を確認することは決して悪いことではありません。
ウィキペディアには、執筆時点でのパディング モードに関するかなりの説明があります。
出力暗号文の長さは、ブロックの長さ、暗号モード、およびパディングが使用されているかどうかによって異なります。
ブロック暗号であっても、入力と等しい暗号出力長を作成する CTS のような暗号モードがあります。
1 について: 入力データの長さが暗号ブロック サイズの倍数であり、パディングが使用されている場合、パディング長を指定するには少なくとも 1 バイトが必要なため、出力長は 1 ブロック大きくなります。
2 について: 出力長はブロック長の倍数でなければならないため、入力長 + (入力長modブロック長) になります。