我阅读了一些关于使用Java密码加密和解密数据的示例。例如:
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
keyGenerator.init(256, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, secretKey);
我有两个关于解密过程的问题。
- 尽管IV是必需的,但我们可以使用
Cipher.init(Cipher.ENCRYPT_MODE, Key)
使其隐含。随机IV将自动应用于它。但是,在解密模式下,必须使用相同的IV。这是否意味着应该只使用Cipher.init(int opmode, Key key, AlgorithmParameters params)
,而IV应该从加密中获得,存储并传递到这里
除了"KeyGenerator",我还看到了使用"SecretKeyFactory"生成密钥的示例:
String key = ...
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKeySpec keySpec = factory.generateSecret(new DESKeySpec(key));
如果我把最后一行改为,我想我可以把它用于AES
SecretKeySpec keySpec = factory.generateSecret(new SecretKeySpec(key,"AES"));
- 我对何时使用
SecretKeyFactory
生成密钥以及何时使用KeyGenerator
感到困惑。后者似乎是生成一个随机密钥,前者是从给定的密钥材料中生成的。那么,这是否意味着在解密模式下,只能使用SecretKeyFactory
这是否意味着应该只使用
Cipher.init(int opmode, Key key, AlgorithmParameters params)
,而IV应该从加密中获得,存储并传递到这里?
是的,正是这样,除非你能够用其他方式交流。一般来说,尽管IV在加密过程中是随机化的,然后以密文为前缀。对于AES-CBC,它总是与块大小相同:16字节。
这是否意味着在解密模式下,只能使用
SecretKeyFactory
?
是的,尽管AES有一个简洁的小快捷方式;你可以简单地做:
SecretKey aesKey = new SecretKeySpec(keyBytes, "AES");
这是因为SecretKeySpec
实现了SecretKey
。对于3DES密钥来说,这不是一个好主意,因为这意味着DES的奇偶校验位设置不正确。然而,现代密钥,如AES密钥和HMAC密钥,仅由随机数据组成,因此对于那些密钥来说,这是可以的。有一点需要注意:如果你试图以这种方式在硬件设备中生成密钥,那将是一个问题:它必须保存在软件中。
请注意,我不会过多地研究密钥管理以及如何创建密钥。我已经在这里回答了这个问题,尽管这个答案肯定还远远不够完整。见鬼,你可以用骰子在电话上分享号码,我只在乎:(