我正在尝试使用Java生成一个密钥。老实说,我在密钥、密码、密码和加密方面没有那么丰富的经验。
不管我从这个网站上搜索了什么,我都认为这是一个很常见的问题。我做了一些阅读,并想出了我写的代码:
Security.setProperty("crypto.policy", "unlimited");
String valueToEncode = "some_random_text";
SecureRandom secureRandom = new SecureRandom();
byte[] salt = new byte[256];
secureRandom.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec("some_random_password".toCharArray(), salt, 65536, 256); // AES-256
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWITHHMACSHA512ANDAES_256");
byte[] key = secretKeyFactory.generateSecret(keySpec).getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
byte[] ivBytes = new byte[16];
secureRandom.nextBytes(ivBytes);
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encValue = cipher.doFinal(valueToEncode.getBytes(StandardCharsets.UTF_8));
byte[] finalCiphertext = new byte[encValue.length + 2 * 16];
System.arraycopy(ivBytes, 0, finalCiphertext, 0, 16);
System.arraycopy(salt, 0, finalCiphertext, 16, 16);
System.arraycopy(encValue, 0, finalCiphertext, 32, encValue.length);
System.out.println(finalCiphertext.toString());
这是根据我在另一篇文章中看到的答案而修改的。但我仍然得到“无效长度”错误。
我得到的错误是:
Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 20 bytes
at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)
at com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:93)
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:591)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
at javax.crypto.Cipher.implInit(Cipher.java:805)
at javax.crypto.Cipher.chooseProvider(Cipher.java:863)
at javax.crypto.Cipher.init(Cipher.java:1395)
at javax.crypto.Cipher.init(Cipher.java:1326)
at com.att.logicalprovisioning.simulators.Trial.main(Trial.java:47)
Trial.java:47
是行:cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
有没有一种适合所有解决方案的方法?还是因为我缺乏理解?
任何帮助都将不胜感激。
发布于 2022-11-10 11:08:33
您的密钥有20个字节长,因为secretKeyFactory.generateSecret(keySpec).getEncoded()
返回密码some_random_password
。
修复代码的一个简单方法是使用键派生PBKDF2WithHmacSHA512
而不是PBEWITHHMACSHA512ANDAES_256
。这将根据密码和salt生成指定长度的密钥:
...
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
...
然而,PBEWITHHMACSHA512ANDAES_256
也可以应用。该算法使用PBKDF2WithHmacSHA512
和随后的AES加密指定密钥派生。该实现在功能上与您的实现相同,但需要对代码进行更多的更改:
...
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 65536, ivParameterSpec);
PBEKeySpec keySpec = new PBEKeySpec("some_random_password".toCharArray());
SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWITHHMACSHA512ANDAES_256");
SecretKey secretKey = kf.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("PBEWITHHMACSHA512ANDAES_256");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] encValue = cipher.doFinal(valueToEncode.getBytes(StandardCharsets.UTF_8));
...
另外两个问题是:
byte[] salt = new byte[16]
.finalCiphertext.toString()
只返回对象s. here的类和十六进制哈希码。对于有意义的输出,可以使用Base64或byte[]
的十六进制编码,例如:byte[]
https://stackoverflow.com/questions/74386927
复制相似问题