Я пытаюсь расшифровать ключ, зашифрованный функцией Java Triple DES, используя функцию PHP mcrypt, но не повезло. Найдите ниже код java
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class Encrypt3DES { private byte[] key; private byte[] initializationVector; public Encrypt3DES(){ } public String encryptText(String plainText, String key) throws Exception{ //---- Use specified 3DES key and IV from other source -------------- byte[] plaintext = plainText.getBytes(); byte[] myIV = key.getBytes(); byte[] tdesKeyData = {(byte)0xA2, (byte)0x15, (byte)0x37, (byte)0x08, (byte)0xCA, (byte)0x62, (byte)0xC1, (byte)0xD2, (byte)0xF7, (byte)0xF1, (byte)0x93, (byte)0xDF, (byte)0xD2, (byte)0x15, (byte)0x4F, (byte)0x79, (byte)0x06, (byte)0x67, (byte)0x7A, (byte)0x82, (byte)0x94, (byte)0x16, (byte)0x32, (byte)0x95}; Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding"); SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede"); IvParameterSpec ivspec = new IvParameterSpec(myIV); c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec); byte[] cipherText = c3des.doFinal(plaintext); sun.misc.BASE64Encoder obj64=new sun.misc.BASE64Encoder(); return obj64.encode(cipherText); } public String decryptText(String encryptText, String key) throws Exception{ byte[] initializationVector = key.getBytes(); byte[] tdesKeyData = {(byte)0xA2, (byte)0x15, (byte)0x37, (byte)0x08, (byte)0xCA, (byte)0x62, (byte)0xC1, (byte)0xD2, (byte)0xF7, (byte)0xF1, (byte)0x93, (byte)0xDF, (byte)0xD2, (byte)0x15, (byte)0x4F, (byte)0x79, (byte)0x06, (byte)0x67, (byte)0x7A, (byte)0x82, (byte)0x94, (byte)0x16, (byte)0x32, (byte)0x95}; byte[] encData = new sun.misc.BASE64Decoder().decodeBuffer(encryptText); Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede"); IvParameterSpec ivspec = new IvParameterSpec(initializationVector); decipher.init(Cipher.DECRYPT_MODE, myKey, ivspec); byte[] plainText = decipher.doFinal(encData); return new String(plainText); } }
Я хочу написать функцию PHP, эквивалентную функции decryptText Java выше. я нахожу затруднение в генерировании точного значения IV, генерируемого кодом Java для шифрования, которое требуется для дешифрования.
Это эквивалент PHP вашего Java-кода (я скопировал PKCS # 5-padding из комментария 20-Sep-2006 07:56
из ссылки mcrypt
)
function encryptText($plainText, $key) { $keyData = "\xA2\x15\x37\x08\xCA\x62\xC1\xD2" . "\xF7\xF1\x93\xDF\xD2\x15\x4F\x79\x06" . "\x67\x7A\x82\x94\x16\x32\x95"; $padded = pkcs5_pad($plainText, mcrypt_get_block_size("tripledes", "cbc")); $encText = mcrypt_encrypt("tripledes", $keyData, $padded, "cbc", $key); return base64_encode($encText); } function decryptText($encryptText, $key) { $keyData = "\xA2\x15\x37\x08\xCA\x62\xC1\xD2" . "\xF7\xF1\x93\xDF\xD2\x15\x4F\x79\x06" . "\x67\x7A\x82\x94\x16\x32\x95"; $cipherText = base64_decode($encryptText); $res = mcrypt_decrypt("tripledes", $keyData, $cipherText, "cbc", $key); $resUnpadded = pkcs5_unpad($res); return $resUnpadded; } function pkcs5_pad ($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } function pkcs5_unpad($text) { $pad = ord($text{strlen($text)-1}); if ($pad > strlen($text)) return false; if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false; return substr($text, 0, -1 * $pad); }
Но есть некоторые проблемы, о которых вы должны знать:
String.getBytes()
без указания кодировки. Это делает ваш код не переносимым, если ваш чистый текст содержит не ASCII-символы, такие как umlauts, потому что Java использует набор символов по умолчанию. Если вы можете изменить это, я бы это сделал. Я рекомендую использовать utf-8 с обеих сторон (Java и PHP). Конечно, если вам нужно выполнить некоторые заданные требования, вы не сможете изменить свой метод.
Ответ почти хороший! Просто $keyData
и $key
$encText = mcrypt_encrypt("tripledes", $keyData, $padded, "cbc", $key);
а также
$res = mcrypt_decrypt("tripledes", $keyData, $cipherText, "cbc", $key);
иначе вы всегда будете использовать тот же самый ключ 3DES. И лучше переименовать $keyData
в $iv
.
В любом случае, спасибо за образец Java и перевод Php-Java.