次のコードを使用して、JAVA で暗号化された文字列を復号化しようとしています。
SecretKey SecretKey = new SecretKeySpec(build3DesKey(key), "DESede"); 暗号 cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.DECRYPT_MODE, SecretKey); byte[] b = cipher.doFinal(str2ByteArray(dest)); 文字列デコーダ = new String(b, "utf-8");
private static byte[] build3DesKey(String keyStr) throws Exception { byte[] キー = 新しいバイト[24]; byte[] temp = keyStr.getBytes("utf-8"); if (key.length > temp.length) { System.arraycopy(temp, 0, key, 0, temp.length); } それ以外 { System.arraycopy(temp, 0, key, 0, key.length); } リターンキー; }
PHP バージョンで同じ結果を得るにはどうすればよいですか? PHPで書いてみましたが、出力が間違っていました。
$data = '69C16E8142F2BDDE7569842BB0D68A3176624264E...'; $key = 'rpwdvbppnrvr56m123 #'; 関数復号化($data, $secret) { //ハッシュからキーを生成 $key = md5(utf8_encode($secret), true); //$key の最初の 8 バイトを $key の最後に追加します。 $key .= substr($key, 0, 8); $data = Base64_decode($data); $data = mcrypt_decrypt('tripledes', $key, $data, 'ecb'); $block = mcrypt_get_block_size('tripledes', 'ecb'); $len = strlen($data); $pad = ord($data[$len-1]); return substr($data, 0, strlen($data) - $pad); } var_dump(utf8_encode(Decrypt($data, $key)));
関数
リーリーbuild3DesKey()
短すぎる 3DES キーの末尾に 0x00 値を埋め込んで 24 バイトに拡張します。長すぎるキーの場合、末尾は単純に切り詰められます。 PHP では、次のように実装できますbuild3DesKey()
:関数
str2ByteArray()
が欠落していますが、その機能は推測できます。あなたの例では暗号文が 16 進数でエンコードされているため、この関数は 16 進数のデコードを実行するだけのようです。 PHP では、str2ByteArray()
に相当するのはhex2bin()
です。したがって、復号化の可能な実装は次のとおりです (PHP/OpenSSL を使用):
リーリーこれらの入力データは、Java コードで同じプレーンテキストを返します。
コードとの違い:
コードでは、非推奨の
mcrypt
が使用されています。セキュリティ上の理由から、現在は使用しないでください。上記のコードに示すように、より良い代替手段は PHP/OpenSSL です。さらに、実装されたキー導出は間違っています。たとえば、Java コードではまったく使用されていない MD5 ダイジェストが適用されています。###安全性:### これは古いアプリかもしれませんが、セキュリティに関するいくつかの注意事項:
キー導出build3DesKey()- は安全ではありません。キーマテリアルが文字列の場合、通常はキーではなくパスワードです。したがって、Argon2 や PBKDF2 などの信頼できるキー導出関数を使用する必要があります。
- 3DES/TripleDES は廃止され、まだ非推奨になっていない唯一のバリアントである Triple Length Key (3TDEA) も間もなく非推奨になる予定で、比較的遅いです。今日の標準は、AES を適用することです。
des-ede3 は ECB モードを適用しますが、これも安全ではありません。 AES-GCM などの認証された暗号化を使用する必要があります。