简体   繁体   English

需要与Java等价的PHP代码的3DES解密

[英]Need Java equvalent for 3DES decryption of PHP code

This is the PHP code I have. 这是我拥有的PHP代码。

function decrypt($s_input, $s_key, $s_iv) { 
   $s_decrypted = pack("H*" , $s_input); // Hex to binary
   $s_decrypted = mcrypt_decrypt (MCRYPT_3DES, $s_key, $s_decrypted, MCRYPT_MODE_CBC, $s_iv);  // 3des decryption
  return $s_decrypted; 
}
echo encrypt('c37551bb77f741d0bcdc16497b4f97b1','123456781234567812345678','12345678' );

what it basically does is to decrypt a 3des encrypted string (first it convert the hex string to binary using pack function and then does the actual decryption). 它基本上要做的是解密3des加密的字符串(首先使用pack函数将十六进制字符串转换为二进制,然后进行实际解密)。

This perfectly works in PHP-4 and prints the "Hello World" message. 这完全可以在PHP-4中工作,并显示“ Hello World”消息。

However, if I run the equivalent java code (jdk 1.6), it prints garbage output as - ¬ªmjV=7xl_ÓÄ^›*?. 但是,如果我运行等效的Java代码(jdk 1.6),则将垃圾输出显示为-¬mjV=7xl_ÓÄ^› *?。

Can someone help to troubleshoot this? 有人可以帮助解决此问题吗? Why Java is not properly decrypting the hex string. 为什么Java无法正确解密十六进制字符串。

private static String decrypt(String inputStr, String keyStr, String ivStr) throws Exception {

    IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
    SecretKeySpec key = new SecretKeySpec(keyStr.getBytes(), "DESede");
    inputStr = hexToString(inputStr, 2);

    Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, key, iv);
    byte[] decrypted = cipher.doFinal(inputStr.getBytes());

    return new String(decrypted);
}

private static String hexToString(String input, int groupLength) {
    StringBuilder sb = new StringBuilder(input.length() / groupLength);
    for (int i = 0; i < input.length() - groupLength + 1; i += groupLength) {
        String hex = input.substring(i, i + groupLength);
        sb.append((char) Integer.parseInt(hex, 16));
    }
    return sb.toString();
}

public static void main(String[] args) throws Exception {
    String decryptSignature = decrypt("c37551bb77f741d0bcdc16497b4f97b1", "123456781234567812345678", "12345678");
    System.out.println(decryptSignature);
}

There are a few things you should check. 您需要检查几件事。 You might find Encryption using AES-128 in Java to be of some assistance. 您可能会发现在Java中使用AES-128进行加密会有所帮助。 There could be issues with differences between how you are handling keys in the PHP and Java code. 在PHP和Java代码中处理键的方式之间可能存在差异。 Calling getBytes() on a String in Java without an encoding is almost always a bad idea. 在Java中对String调用getBytes()而不进行编码几乎总是一个坏主意。 Plus the padding used could be a problem. 加上使用的填充可能是个问题。 From what I've seen PHP pads with null characters by default, which does not correspond to NoPadding in Java. 从我已经看到的PHP NoPadding默认情况下为null字符,这与Java中的NoPadding不对应。 Finally, the hexToString method should return a byte[] instead of a String . 最后, hexToString方法应该返回一个byte[]而不是String Add the result of calling Integer.parseInt(hex, 16) into an array: 将调用Integer.parseInt(hex, 16)的结果添加到数组中:

byte[] results = new byte[input.length() / groupLength];
...
    //inside the loop
    results[i / groupLength] = (byte) Integer.parseInt(hex, 16);
...
return results;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM