为了账号安全,请及时绑定邮箱和手机立即绑定

Java AES/CBC解密后的初始字节不正确

Java AES/CBC解密后的初始字节不正确

长风秋雁 2019-07-08 15:34:32
Java AES/CBC解密后的初始字节不正确下面的例子有什么问题?问题是解密字符串的第一部分是无意义的。不过,其余的都没问题,我.Result: `£eB6O�geS��i are you? Have a nice day.@Testpublic void testEncrypt() {   try {     String s = "Hello there. How are you? Have a nice day.";     // Generate key     KeyGenerator kgen = KeyGenerator.getInstance("AES");     kgen.init(128);     SecretKey aesKey = kgen.generateKey();     // Encrypt cipher     Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");     encryptCipher.init(Cipher.ENCRYPT_MODE, aesKey);     // Encrypt     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();     CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, encryptCipher);     cipherOutputStream.write(s.getBytes());     cipherOutputStream.flush();     cipherOutputStream.close();     byte[] encryptedBytes = outputStream.toByteArray();     // Decrypt cipher     Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");     IvParameterSpec ivParameterSpec = new IvParameterSpec(aesKey.getEncoded());     decryptCipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);     // Decrypt     outputStream = new ByteArrayOutputStream();     ByteArrayInputStream inStream = new ByteArrayInputStream(encryptedBytes);     CipherInputStream cipherInputStream = new CipherInputStream(inStream, decryptCipher);     byte[] buf = new byte[1024];     int bytesRead;     while ((bytesRead = cipherInputStream.read(buf)) >= 0) {         outputStream.write(buf, 0, bytesRead);     }     System.out.println("Result: " + new String(outputStream.toByteArray()));   }    catch (Exception ex) {     ex.printStackTrace();   }}
查看完整描述

3 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

在我看来,您没有正确地处理您的初始化向量(IV)。我已经很久没读到AES,IVs和块链了,但是你的台词

IvParameterSpec ivParameterSpec = new IvParameterSpec(aesKey.getEncoded());

似乎不太好。在AES中,您可以将初始化向量看作密码实例的“初始状态”,这种状态是您无法从密钥中获得的一些信息,而是从加密密码的实际计算中获得的。(人们可能会说,如果可以从密钥中提取IV,那么它就没用了,因为密钥在初始阶段已经给了密码实例)。

因此,您应该在加密结束时将IV作为字节[]从密码实例中获取。

  cipherOutputStream.close();
  byte[] iv = encryptCipher.getIV();

你应该初始化你的Cipher在……里面DECRYPT_MODE使用这个字节[]:

  IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

那么,你的解密应该没问题。希望这能帮上忙。


查看完整回答
反对 回复 2019-07-08
  • 3 回答
  • 0 关注
  • 941 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号