【发布时间】:2021-01-18 05:56:30
【问题描述】:
我有一个加密和解密字符串的 java 应用程序。它生成一个用于加密的密钥和一个用于解密的密钥。
密钥生成:
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
char[] passwordChars = password.toCharArray();
KeySpec spec = new PBEKeySpec(passwordChars, salt.getBytes(), iterations, 256);
SecretKey key = keyFactory.generateSecret(spec);
byte[] passwordHash = key.getEncoded();
SecretKey secretKey = new SecretKeySpec(key.getEncoded(), "AES");
我的目标是让加密和解密密钥的密码保持不变。但是每个人都有不同的盐。这是可能的还是我需要为两个键使用相同的盐?
每当我尝试更改解密密钥的盐时,我都会收到此错误:
javax.crypto.AEADBadTagException: Tag mismatch!
at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:623)
at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1118)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1055)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:855)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2207)
【问题讨论】:
-
请指定盐和迭代。
-
盐用于从密码生成密钥(使用 PBKDF2)。更改盐或迭代计数会更改生成的密钥,所以不,您不能这样做,AES 使用对称密钥,因此加密和解密密钥必须相同。
-
Iterations = 6000 // key1 的盐 = “salt”(加密密钥) // key2 的盐 = “test”(解密密钥)。目前这只是一个测试应用程序,所以我还没有生成随机盐。
-
谢谢马克。我的加密和解密密钥实际上是不同的。只要生成的密钥使用相同的密码、盐和 IV,应用程序就可以工作。我只是想确保没有办法在每个密钥生成时随机化盐。
-
两条消息之间可能不同,但如果您使用的是 AES-GCM,则原始密钥必须相同。如果您使用相同的密码/盐/迭代,则密钥将相同。您应该只在需要不同的密钥时更改参数(例如:从一条消息到另一条消息),而不是在加密和解密之间。您亲眼目睹了更换盐时会发生什么。
标签: java encryption salt