Java AES CBC解密

PHP加密function

$privateKey = "1234567812345678"; $iv = "1234567812345678"; $data = "Test string"; $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv); echo(base64_encode($encrypted)); Result: iz1qFlQJfs6Ycp+gcc2z4w== 

当我尝试使用下面的函数在Java中解密此结果时,我得到的所有内容都是ì š@ÔBKxnfÈ~¯Ô’M而我期待“测试字符串”。 我错的任何想法? 谢谢

 public static String decrypt() throws Exception{ try{ String Base64EncodedText = "iz1qFlQJfs6Ycp+gcc2z4w=="; String decodedText = com.sun.xml.internal.messaging.saaj.util.Base64.base64Decode(Base64EncodedText); String key = "1234567812345678"; String iv = "1234567812345678"; javax.crypto.spec.SecretKeySpec keyspec = new javax.crypto.spec.SecretKeySpec(key.getBytes(), "AES"); javax.crypto.spec.IvParameterSpec ivspec = new javax.crypto.spec.IvParameterSpec(iv.getBytes()); javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/NoPadding"); cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keyspec, ivspec); byte[] decrypted = cipher.doFinal(decodedText.getBytes()); String str = new String(decrypted); return str; }catch(Exception e){ return null; } } 

编辑:从Java 8开始,Java现在包含一个可接受的Base64类java.util.Base64


这条线

 String decodedText = com.sun.xml.internal.messaging.saaj.util.Base64.base64Decode(Base64EncodedText); 

看起来不对劲 相反,使用apache commons编解码器类或Harder base64类。 mcrypt使用的默认填充,零填充,可以说是错误的,并且很难在其他语言中使用结果。 mcrypt_encrypt网页的用户评论部分提供了如何执行此操作的示例。

这是一个小例子,它使用apache commons类来解密你的字符串。

 import java.nio.charset.Charset; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; public class AESToy3 { private static final Charset ASCII = Charset.forName("US-ASCII"); public static void main(String[] args) throws Exception { String base64Cipher = "iz1qFlQJfs6Ycp+gcc2z4w=="; byte [] cipherBytes = Base64.decodeBase64(base64Cipher); byte [] iv = "1234567812345678".getBytes(ASCII); byte [] keyBytes = "1234567812345678".getBytes(ASCII); SecretKey aesKey = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING"); cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv)); byte[] result = cipher.doFinal(cipherBytes); System.out.println(Hex.encodeHexString(result)); } } 

这会产生以下输出:

 5465737420737472696e670000000000 

当解码为ASCII并删除尾随零时,会给出Test string