- 键!=密码
SecretKeySpec
需要键,而不是密码。见下文
- 这可能是由于策略限制导致无法使用32个字节的密钥。看到其他答案
问题是数字1:您要传递密码而不是密钥。
AES仅支持16、24或32字节的密钥大小。您要么需要提供准确的金额,要么从键入的内容中得出密钥。
有多种方法可以从密码短语中获取密钥。Java为此提供了PBKDF2实现。
我使用了埃里克森的答案来描绘出完整的图片(仅加密,因为解密是相似的,但包括分割密文):
SecureRandom random = new SecureRandom();byte[] salt = new byte[16];random.nextBytes(salt);KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256); // AES-256SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");byte[] key = f.generateSecret(spec).getEnpred();SecretKeySpec keySpec = new SecretKeySpec(key, "AES");byte[] ivBytes = new byte[16];random.nextBytes(ivBytes);IvParameterSpec iv = new IvParameterSpec(ivBytes);Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");c.init(Cipher.ENCRYPT_MODE, keySpec, iv);byte[] encValue = c.doFinal(valueToEnc.getBytes());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);return finalCiphertext;
其他注意事项:
- 始终使用完全限定的密码名称。
AES
在这种情况下不适用,因为不同的JVM / JCE提供程序可能对 *** 作和填充模式使用不同的默认值。使用AES/CBC/PKCS5Padding
。不要使用ECB模式,因为它在语义上并不安全。 - 如果您不使用ECB模式,则需要将IV和密文一起发送。这通常是通过在IV前面加上密文字节数组来完成的。IV是自动为您创建的,您可以通过它获得
cipherInstance.getIV()
。 - 每当您发送邮件时,都需要确保该邮件在发送过程中没有被更改。很难用MAC正确实现加密。我建议您使用CCM或GCM之类的身份验证模式。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)