【问题标题】:Java encryption by client and decryption by server, using PBKDF2WithHmacSHA1 and AES/CBC/PKCS5PaddingJava 客户端加密和服务器解密,使用 PBKDF2WithHmacSHA1 和 AES/CBC/PKCS5Padding
【发布时间】:2012-01-09 08:15:18
【问题描述】:

只要私钥保密,我就会确保安全保密,并且在解密时我的应用程序中出现以下错误:javax.crypto.BadPaddingException: Given final block not proper padding

代码:

// Encryption, client side
byte[] plainData = "hello plaintext!".getBytes("UTF-8");
byte[] salt = new byte[64];
new SecureRandom().nextBytes(salt);
KeySpec spec = new javax.crypto.spec.PBEKeySpec("password".toCharArray(), salt, 1024,   256);
SecretKey sk = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sk.getEncoded(), "AES"));
byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal(plainData);
System.out.println("ciphertext: "+new String(ciphertext, "UTF-8")); // cipher

// Decryption, server side
KeySpec spec2 = new javax.crypto.spec.PBEKeySpec("password".toCharArray(), salt, 1024, 256);
SecretKey sk2 = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec2);
Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher2.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sk2.getEncoded(), "AES"), new IvParameterSpec(iv)); // Get the same IV value from client/encryptor aswell, still random
String plaintext = new String(cipher2.doFinal(ciphertext), "UTF-8");
System.out.println("decrypted plaintext: "+plaintext); // plain

是盐的随机性导致问题吗?

当我在客户端使用对象引用时,我可以很好地解密它,但我需要在服务器上拥有自己的实例。

非常感谢您纠正我的错误!

*编辑:* 代码已更新和更正

【问题讨论】:

  • 填充异常指向此代码顺便说一句:String plaintext = new String(cipher2.doFinal(ciphertext), "UTF-8");
  • 您不使用 SSL 有什么原因吗?

标签: java encryption cryptography padding jce


【解决方案1】:

通过快速查看您的代码,我可以看到您正在客户端和服务器端创建不同的盐。为了让服务器端能够解密该盐,密钥必须相同。

现在我不是 Java 开发人员,但所有其他代码对我来说看起来都不错,但就像我说的,如果您在每一端创建不同的盐,解密将无法正常工作。

【讨论】:

  • 我注释掉了盐的随机化并且异常消失了。但是明文没有出来:密文:n?}@cX?? \??v6z???^d8,???F(/解密明文: $GA????%??
  • 看来我也必须将相同的 IV 值发送到服务器
  • @gorn:是的,您需要在两面使用相同的 IV 和相同的盐。不过,您可以从密码和盐生成 IV。
  • 这个不用说,但是要确保你的salt和secret key是相同的,用于加密和解密,否则这将永远无法工作。
猜你喜欢
  • 1970-01-01
  • 2021-08-13
  • 2018-11-28
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-27
相关资源
最近更新 更多