Java 为什么Lambda在初始化后生成相同的加密密钥,以及如何修复它?

Java 为什么Lambda在初始化后生成相同的加密密钥,以及如何修复它?,java,aws-lambda,amazon-cloudfront,jce,Java,Aws Lambda,Amazon Cloudfront,Jce,在从AWS Lambda生成密钥对时,我注意到了一些奇怪的事情——每次我运行代码时,它都会生成相同的密钥。我知道Lambda容器在每次调用后都会被冻结,这可能就是从内存加载底层JCE类并保持其初始状态的原因。所讨论的代码相对简单: KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC"); keyPairGen.initialize(2048); KeyPair keyPair = keyPairGen.gen

在从AWS Lambda生成密钥对时,我注意到了一些奇怪的事情——每次我运行代码时,它都会生成相同的密钥。我知道Lambda容器在每次调用后都会被冻结,这可能就是从内存加载底层JCE类并保持其初始状态的原因。所讨论的代码相对简单:

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC");
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();

return new RSAKey.Builder(rsaPublicKey).privateKey(rsaPrivateKey)
            .keyID(kid).keyUse(KeyUse.SIGNATURE)
我尝试了vanilla provider和Bouncy Castle,但结果是一样的——当Lambda“温暖”时,密钥对是相同的。一旦容器从“冷”状态终止并重新启动,我就会得到一组新的不同的密钥

我还使用AWS Cognito,该服务通过API网关和CloudFront提供


如何“刷新”底层JCE类?回答我自己的问题,罪魁祸首实际上是CloudFront。即使在API网关中关闭了API缓存,CloudFront仍然会缓存一些API请求的响应

如果有人遇到同样的问题,解决方案是通过向请求URL添加查询参数来“破坏”CloudFront缓存:

GET /api/generateKeyPair?timestamp=1507843759370

是否
keyPairGen.initialize(2048,new SecureRandom())
help?不幸的是,它没有。我注意到它与我的身份验证会话有关,在注销Cognito和重新登录之后,生成的密钥对是不同的。有些东西,某个地方被缓存了,缓存在API网关中肯定被关闭了。明白了-肯定是CloudFront!对于您创建的CloudFront发行版,您需要为您的应用程序正确配置CloudFront。默认行为是将不带
缓存控制
头的响应缓存24小时。