最初のステートメントを最初に処理する必要があると思います。Open SSL ライブラリを使用する場合、PHP が AES-128-CBC 暗号化を行う方法に矛盾がありますか?
AES のRFC3602を調べると、セクション 4 にいくつかのテスト ベクトルが見つかるため、これを尋ねています。最初に試したのは次のとおりです。
ケース #1: AES-CBC と 128 ビット キーを使用して 16 バイト (1 ブロック) を暗号化する
キー: 0x06a9214036b8a15b512e03d534120006
IV : 0x3dafba429d9eb430b422da802c9fac41
Painttext : "単一ブロック メッセージ"
Cphertext: 0xe353779c1079aeb82708942dbe77181a
次のコードでオープン SSL ライブラリを使用します。
echo bin2hex(openssl_encrypt($str, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv));
あなたは実際に戻ってきます:
e353779c1079aeb82708942dbe77181ab97c825e1c785146542d396941bce55d
これで問題なく復号化でき、最初の 32 バイトは予想される暗号文「e353779c1079aeb82708942dbe77181a」です。ただし、Open SSL ライブラリから返された暗号文の末尾には、さらに 32 バイトあるようです。どうしてこれなの?この質問は次に関連します。
私が楽しみのために行っていることの一部として、AES CBC モードの暗号化をゼロから実装しようとしています。これを行うために現在持っているコードは次のとおりです(以前に参照したRFCと、 「ブロック暗号操作モード」WikipediaページのCBC図に基づいています):
public function cbcEncrypt($str, $iv, $key) {
$bl = 16;
$bs = str_split($str,$bl);
$pv = null;
$r = '';
foreach($bs as $b) {
if($pv === null) $pv = $iv;
if(strlen($b)<$bl) $b = $this->pkcs7Pad($b, $bl);
$pv = openssl_encrypt($b^$pv, 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
$r .= $pv;
}
return $r;
}
現時点では、このコードが現在のテスト用の 16 バイト文字列よりも長い文字列では機能しないと確信していますが、このコードを Open SSL 実装と並べて実行して比較しました。CBC 実装による戻り値は次のとおりです。
e353779c1079aeb82708942dbe77181a8b1ccc6f8cd525ffe22d6327d891a063
次の方法で呼び出された場合:
$crypto = new CryptoTools();
$enc = $crypto->cbcEncrypt('Single block msg',hex2bin("3dafba429d9eb430b422da802c9fac41"),hex2bin("06a9214036b8a15b512e03d534120006"));
ここでも、最初の 32 バイトは正しいですが、2 番目の 32 バイトが追加されていますが、CBC の Open SSL 実装とは完全に異なります。理由の手がかりはありますか?
また、ECB モードの Open SSL 実装は 32 バイトの文字列を返します。これは、現在長さが 16 バイトを超える CBC 暗号化文字列を意味します。$pv の新しい値は長さが 32 バイトになり、2 番目の実際には $pv の長さは常に 16 バイトであってはならないのに、プレーン テキスト ブロックですか? 通常、$pv を 32 バイトから 16 バイトに切り詰めることは受け入れられますか?
念のため、上記のコードの pkcs7Pad メソッドは次のようになります。
public function pkcs7Pad($str, $b = 8) {
if(trim($str) == '') return false;
if((int)$b < 1) return false;
$p = $b - (strlen($str) % $b);
return $str . str_repeat(chr($p),$p);
}
どんな助けでも大歓迎です。言うまでもなく、人々は通常、確かにPHPで車輪を再発明しようとするほど愚かではないため、これに関するドキュメントはあまりありません...