我正在使用AES进行加密。我的客户正在加密一些敏感数据,同时将数据发布到我的Web API。在将它们插入数据库之前,我的代码将解密这些字段。
最初我们同意使用固定密钥。以下是代码:
public class AESEncryptor {
private static final String ALGO = "AES";
private static final String keyVal = "!5Po4@j82Adsu39/*na3n5";
public static String encrypt(String data) {
try {
Key key = genKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(data.getBytes());
return Base64.encodeBase64String(encVal);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decrypt (String encryptedData) throws Exception{
Key key = genKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] data = Base64.decodeBase64(encryptedData);
byte[] decByptes = c.doFinal(data);
return new String(decByptes);
}
private static Key genKey() throws Exception {
fixKeyLength();
return new SecretKeySpec(keyVal.getBytes(), ALGO);
}
}
然后另一方建议我们切换到KeyGenerator
以生成随机安全密钥。如下所示。
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
final byte[] nonce = new byte[32];
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(nonce);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(16 * 8, nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
我不确定这是可能的。因为正确的解密依赖于相同的密钥进行加密。如果密钥是随机的,我的API将如何知道每次使用哪个密钥?或者有解决方案来处理这种情况吗?
答案 0 :(得分:1)
没有办法解决这个问题。对称加密要求双方都知道密钥才能加密和解密。如果密钥每次都是随机的,那么您需要一种方法来传达密钥。
您设计的方案非常差,因为固定密钥意味着被泄露的密钥会导致整个系统崩溃。您还使用了ECB模式,这种模式本质上是不安全的。没有身份验证。
如果要将数据安全地从一方传送到另一方,请使用TLS进行客户端身份验证。这是解决这个问题的行业标准方法,您不必为加密而沾沾自喜。