Encryption 如何实现零停机键旋转
我有几个微服务在AWS中运行,其中一些相互通信,一些具有外部客户机或是外部服务的客户机 为了实现我的服务,我需要一些秘密(RSA密钥对来签名/验证令牌、对称密钥、API密钥等)。我正在为此使用AWS SecretsManager,它运行良好,但我现在正在实现对键旋转的适当支持,我有一些想法Encryption 如何实现零停机键旋转,encryption,secret-key,aws-secrets-manager,shared-secret,Encryption,Secret Key,Aws Secrets Manager,Shared Secret,我有几个微服务在AWS中运行,其中一些相互通信,一些具有外部客户机或是外部服务的客户机 为了实现我的服务,我需要一些秘密(RSA密钥对来签名/验证令牌、对称密钥、API密钥等)。我正在为此使用AWS SecretsManager,它运行良好,但我现在正在实现对键旋转的适当支持,我有一些想法 我正在使用AWS SecretsManager,定期(约5分钟)获取机密并在本地缓存它们 我正在使用AWS SecretsManager的版本阶段功能,根据需要引用AWS当前版本和AWS以前的版本 假设服
- 我正在使用AWS SecretsManager,定期(约5分钟)获取机密并在本地缓存它们
- 我正在使用AWS SecretsManager的版本阶段功能,根据需要引用AWS当前版本和AWS以前的版本
- 假设在开始时,K具有当前值K1和之前的值K0
- 在与B的通信中,服务A将始终使用(并在本地缓存)K的AWSCURRENT版本,因此在本例中为K1
- 服务B将在其本地缓存中保留版本AWSCURRENT和AWSPREVIOUS,并同时接受[K1,K0]
- 在旋转K时,我首先确保服务B使用的秘密被旋转,以便在刷新间隔结束后,服务B的所有实例都接受[K2,K1],而不是[K1,K0]。在刷新间隔结束之前,的所有实例仍使用K1
- 当刷新间隔结束时,意味着B的所有实例都必须获取K2,我旋转键进行服务,以便A将使用K1或K2,直到刷新间隔结束,然后仅使用K2
- 这就完成了密钥轮换(但是如果K1被认为被泄露了,我们可以再次轮换B的秘密来推出K1并得到[K3,K2])
这是最好的方法还是其他人要考虑?
然后,在某些情况下,我有一个在同一服务中使用的对称密钥J,例如用于加密某个会话的密钥。因此,在对服务C的一个请求中,会话使用密钥J1加密,然后需要在稍后阶段使用J1解密。我有多个C服务实例 这里的问题是,如果加密和解密都使用相同的密钥,那么旋转它会变得更加混乱-如果密钥被旋转为具有值J2,并且一个实例已刷新,以便使用J2进行加密,而另一个实例仍然看不到J2,则解密将失败 我可以在这里看到一些方法:- 加密始终使用AWSCURRENT(J1或J2取决于是否刷新)
- 解密将先尝试AWSCURRENT,然后尝试AWSPREVIOUS,如果两者都失败(因为存储了J2和[J1,J0]所使用的另一个实例的加密),则将请求手动刷新机密([J2,J1]现在已存储),然后再次尝试AWSCURRENT和AWSPREVIOUS
- 所有服务定期(每T秒)向SecretsManager查询
,AWSCURRENT
和自定义标签AWSCURRENT
,并全部接受(如果存在)->所有服务接受[ROTATING
=K1]AWSCURRENT
- 所有客户端都使用
=K1AWSCURRENT
AWSCURRENT
=K1,awexpensing
=K2]ROTATING
添加到K1版本+将AWSCURRENT
移动到K2版本+从K2中移除AWSCURRENT
标签(似乎没有标签的原子交换)。直到T秒过去,一些客户端将使用K2和一些K1,但所有服务都接受这两种AWSCURRENT
=K2,awexpensing
=K1],并且所有客户端都使用AWSCURRENT
=K2级。请注意,K1仍将具有先前的AWSPREVIOUS
阶段
AWSCURRENT
=K2],K1实际上已失效不幸的是,我不知道如何使用内置的旋转机制,因为它需要几个步骤,中间有延迟。一个想法是发明一些自定义步骤,让
setSecret
步骤创建一个CloudWatch cron事件,该事件将在T秒后再次调用该函数,使用步骤swapPending
和removePending
调用它。如果SecretsManager能够自动支持这一点,那就太棒了,例如支持函数返回一个值,指示下一步应该在T秒后调用。对于您的凭证问题,只要服务B支持两个活动凭据,就不必在应用程序中同时保留当前凭据和以前的凭据。为此,您必须确保凭证在准备就绪之前未标记为AWSCURRENT。然后应用程序总是获取并使用