Intereting Posts
php htmlentities для декодирования textarea Yii: Как управлять видео при использовании расширения multuploadfiles Как отправить и установить Mime с помощью PEAR Soap Запись в электронную таблицу Документов Google с использованием PHP preg_replace только теги OUTSIDE? (… мы не говорим о полном «анализе html», просто немного уценке) forece обновить страницу клиента со стороны сервера Помогите с потреблением фида JSON с PHP и json_decode Службы приложений и API Google Analytics V3: Аутентификация OAuth2 от сервера к серверу? Echo 'string', в то время как каждая итерация длинного цикла (flush () не работает) MySQL ifnull эквивалент для php В DDD и CQRS для запросов на чтение, что такое стратегия, которая позволяет использовать интерфейсы и простое тестирование? Как программно изменить пароль Gmail? Zend \ Mvc \ Router \ Http \ Метод и дочерние маршруты PHP $ _SERVER vs. $ _SERVER , правильно ли я понимаю страницы man? Заменить точное возникновение Word в PHP?

PHP эквивалент для Java Triple DES шифрование / дешифрование

Я пытаюсь расшифровать ключ, зашифрованный функцией 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); } 

Но есть некоторые проблемы, о которых вы должны знать:

  • В коде Java вы вызываете String.getBytes() без указания кодировки. Это делает ваш код не переносимым, если ваш чистый текст содержит не ASCII-символы, такие как umlauts, потому что Java использует набор символов по умолчанию. Если вы можете изменить это, я бы это сделал. Я рекомендую использовать utf-8 с обеих сторон (Java и PHP).
  • Вы закодировали шифрованный ключ и используете IV как «ключ». Я ни в коем случае не крипто-эксперт, но для меня это просто неправильно и может открыть огромную утечку безопасности.
  • Создайте случайный IV и просто соедините его в начале или в конце вашего сообщения. Поскольку размер IV равен AFAIK, равному размеру блока вашего шифра, вы просто удаляете столько байтов с начала или конца и легко отделяете IV от сообщения.
  • Что касается ключа, лучше всего использовать какой-то метод деривации ключей для генерации ключа с правильным размером с «сгенерированного человеком» пароля.

Конечно, если вам нужно выполнить некоторые заданные требования, вы не сможете изменить свой метод.

Ответ почти хороший! Просто $keyData и $key

 $encText = mcrypt_encrypt("tripledes", $keyData, $padded, "cbc", $key); 

а также

 $res = mcrypt_decrypt("tripledes", $keyData, $cipherText, "cbc", $key); 

иначе вы всегда будете использовать тот же самый ключ 3DES. И лучше переименовать $keyData в $iv .

В любом случае, спасибо за образец Java и перевод Php-Java.