web-dev-qa-db-ja.com

php:openssl_encryptへのmcrypt_encrypt、およびOPENSSL_ZERO_PADDINGの問題

特定のmcrypt_encrypt$key、および$messageに対して、この$iv呼び出しがあります。

$string = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);

mcrypt_encryptの呼び出しをopenssl_encryptの呼び出しに変更して、これを将来にわたって保証します。

$mode = 'des-ede3-cbc'または$mode = '3DES';$options = trueを使用すると、より類似した応答が得られますが、同一ではありません。完璧な一致を得るためにそれを呼び出す他の方法はありますか?

Lorem-ipsum $message + $keyの組み合わせに対してこれ(base64_encoded)を取得しているので、暗号化する前に、いずれかの関数がメッセージにいくらかパディングしていると思い始めています...

mcryptの場合

「Y + JgMBdfI7ZYY3M9lJXCtb5Vgu + rWvLBfjug2GLX7uo = "

openssl用

「Y + JgMBdfI7ZYY3M9lJXCtb5Vgu + rWvLBvte4swdttHY = "

$ optionsを使用してOPENSSL_ZERO_PADDINGを渡してみましたが、1OPENSSL_RAW_DATA、またはtrue)は空の文字列になります...

OPENSSL_ZERO_PADDINGOPENSSL_RAW_DATA | OPENSSL_ZERO_PADDINGも使用しない... :(「OpenSSL 1.0.2g 1 Mar 2016」を使用しています。

既読 this q&aですが、役に立ちません。 onlyone でパディングの問題はありませんが、これまでのところ解決策はありません。 (2番目の答えはmcrypt呼び出しへのaddingpaddingについて話します、私は本当にremoveopenssl暗号化呼び出しからのパディング...

10
yivi

mcrypt_encrypt 入力データがブロックサイズの倍数でない場合、入力データをゼロ埋めします。データ自体に後続ゼロがある場合、これはあいまいな結果につながります。どうやらOpenSSLでは、この場合ゼロパディングを使用できないため、偽の戻り値が説明されています。

これを回避するには、手動でパディングを追加します。

$message = "Lorem ipsum";
$key = "123456789012345678901234";
$iv = "12345678";

$message_padded = $message;
if (strlen($message_padded) % 8) {
    $message_padded = str_pad($message_padded,
        strlen($message_padded) + 8 - strlen($message_padded) % 8, "\0");
}
$encrypted_mcrypt = mcrypt_encrypt(MCRYPT_3DES, $key,
    $message, MCRYPT_MODE_CBC, $iv);
$encrypted_openssl = openssl_encrypt($message_padded, "DES-EDE3-CBC", 
    $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);

printf("%s => %s\n", bin2hex($message), bin2hex($encrypted_mcrypt));
printf("%s => %s\n", bin2hex($message_padded), bin2hex($encrypted_openssl));

これは、両方を同等として出力します。

4c6f72656d20697073756d => c6fed0af15d494e485af3597ad628cec
4c6f72656d20697073756d0000000000 => c6fed0af15d494e485af3597ad628cec
27
Joe