2011-12-16 2 views
6

Je suis en train de décrypter une clé cryptée par Java Triple DES fonction en utilisant la fonction PHP mcrypt mais sans chance. Trouvez ci-dessous le code javaPHP équivalent pour Java Triple DES cryptage/décryptage

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); 

    } 
} 

Je veux écrire une fonction PHP équivalente à la fonction decryptText Java ci-dessus. J'ai des difficultés à générer la valeur IV exacte générée par le code Java pour le chiffrement, qui est nécessaire pour le déchiffrement.

+0

Rubrique connexe - http://stackoverflow.com/questions/20227/how-do-i-use-3des-encryption-decryption-in-java – adatapost

Répondre

9

Ceci est l'équivalent PHP de votre code Java (j'ai copié le PKCS # 5-padding du commentaire 20-Sep-2006 07:56 de 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); 
} 

Mais il y a quelques problèmes que vous devriez être au courant:

  • Dans votre code Java, vous appelez String.getBytes() sans indiquer de codage. Cela rend votre code non portable si votre texte en clair contient des caractères non ASCII tels que les trémas, car Java utilise le jeu de caractères par défaut du système. Si vous pouvez changer cela, je le ferais certainement. Je vous recommande d'utiliser utf-8 des deux côtés (Java et PHP).
  • Vous avez codé en dur la clé de chiffrement et utilisez l'IV comme "clé". Je ne suis en aucun cas un crypto-expert, mais pour moi, c'est juste une erreur et cela peut ouvrir une énorme fuite de sécurité.
  • Créez un IV aléatoire et concattez-le simplement au début ou à la fin de votre message. Puisque la taille de l'IV est AFAIK égale à la taille de bloc de votre chiffre, vous supprimez juste autant d'octets du début ou de la fin et vous avez facilement séparé l'IV du message. En ce qui concerne la clé, il est préférable d'utiliser une méthode key derivation pour générer une clé de bonne taille à partir d'un mot de passe «généré par des humains».

Bien sûr, si vous devez répondre à certaines exigences, vous ne pouvez pas modifier votre méthode.

+0

thnks beaucoup vstm. Je vais vérifier et revenir. – Ranju

+0

son travail génial !! Thnks une tonne pour votre aide !! – Ranju

+0

Je peux changer la valeur d'une variable $ keyData? –

0

La réponse est presque bonne! Il suffit de renverser $keyData et $key dans

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

et

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

sinon vous utilisez toujours la même clé 3DES. Et il est préférable de renommer $keyData à $iv.

Quoi qu'il en soit, merci beaucoup pour l'exemple Java et la traduction Php-Java.