2011-12-16 3 views
6

Я пытаюсь расшифровать ключ, зашифрованный функцией Java Triple DES, используя функцию PHP mcrypt, но без везения. Найдите ниже код JavaPHP Эквивалент для Java Triple DES шифрование/дешифрование

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-функцию, эквивалентную вышеперечисленной Java-функции decryptText. я нахожу затруднение в генерировании точного значения IV, генерируемого кодом Java для шифрования, которое требуется для дешифрования.

+0

Связанная ветка - http://stackoverflow.com/questions/20227/how-do-i-use-3des-encryption-decryption-in-java – adatapost

ответ

9

Это PHP эквивалент кода Java (я скопировал PKCS # 5-отступы от комментария 20-Sep-2006 07:56 из The mcrypt reference)

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 от сообщения.
  • Что касается ключа, то лучше всего использовать какой-то метод key derivation для генерации ключа с правильным размером с «сгенерированного человеком» пароля.

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

+0

thnks много vstm. Я проверю и вернусь. – Ranju

+0

его отлично работает !! thnks тонна для вашей помощи !! – Ranju

+0

Я могу изменить значение переменной $ keyData? –

0

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

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

и

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

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

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

Смежные вопросы