为什么 Lambda 在初始化后生成相同的加密密钥以及如何修复它?
Why does Lambda generate identical cryptographic keys after initialization and how to fix it?
我注意到从 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 是 "warm" 时,相同的密钥对。一旦容器终止并从 "cold" 状态重新启动,我就会得到一组新的不同的密钥。
我也在使用 AWS Cognito,该服务是通过 API Gateway 和 CloudFront 提供的。
关于如何 "refresh" 底层 JCE 类 有什么想法吗?
回答我自己的问题,罪魁祸首实际上是 CloudFront。即使在 API 网关中关闭 API 缓存,CloudFront 仍会缓存某些 API 请求的响应。
如果有人遇到同样的问题,解决方案是 "bust" CloudFront 缓存,方法是将查询参数附加到请求 URL:
GET /api/generateKeyPair?timestamp=1507843759370
我注意到从 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 是 "warm" 时,相同的密钥对。一旦容器终止并从 "cold" 状态重新启动,我就会得到一组新的不同的密钥。
我也在使用 AWS Cognito,该服务是通过 API Gateway 和 CloudFront 提供的。
关于如何 "refresh" 底层 JCE 类 有什么想法吗?
回答我自己的问题,罪魁祸首实际上是 CloudFront。即使在 API 网关中关闭 API 缓存,CloudFront 仍会缓存某些 API 请求的响应。
如果有人遇到同样的问题,解决方案是 "bust" CloudFront 缓存,方法是将查询参数附加到请求 URL:
GET /api/generateKeyPair?timestamp=1507843759370