如果加密器和解密器位于不同的应用程序/服务器中,我可以使用KeyGenerator吗?

时间:2018-01-25 21:13:28

标签: encryption base64 aes secret-key

我正在使用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将如何知道每次使用哪个密钥?或者有解决方案来处理这种情况吗?

1 个答案:

答案 0 :(得分:1)

没有办法解决这个问题。对称加密要求双方都知道密钥才能加密和解密。如果密钥每次都是随机的,那么您需要一种方法来传达密钥。

您设计的方案非常差,因为固定密钥意味着被泄露的密钥会导致整个系统崩溃。您还使用了ECB模式,这种模式本质上是不安全的。没有身份验证。

如果要将数据安全地从一方传送到另一方,请使用TLS进行客户端身份验证。这是解决这个问题的行业标准方法,您不必为加密而沾沾自喜。