本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
数据密钥缓存详细信息
大多数应用程序可以使用默认数据密钥缓存实施,而无需编写自定义代码。本节介绍了默认实施以及有关选项的一些详细信息。
数据密钥缓存的工作方式
在加密或解密数据的请求中使用数据密钥缓存时,AWS Encryption SDK先在缓存中搜索与请求匹配的数据密钥。如果找到有效的匹配项,它使用缓存的数据密钥加密数据。否则,它生成新的数据密钥,就像没有缓存一样。
不会在未知大小的数据中使用数据密钥缓存,如流式数据。这样缓存 CMM 就可以正确强制执行最大字节数阈值。为了避免该行为,请将消息大小添加到加密请求中。
除缓存外,数据密钥缓存还使用缓存加密材料管理器(缓存 CMM)。缓存 CMM 是一种专用的加密材料管理器(CMM),该管理器与缓存和基础 CMM 进行交互。(在指定主密钥提供程序或密钥环时,AWS Encryption SDK 将创建一个默认 CMM。) 缓存 CMM 缓存其基础 CMM 返回的数据密钥。缓存 CMM 还强制执行您设置的缓存安全阈值。
为了防止从缓存中选择错误的数据密钥,所有兼容的缓存 CMM 都要求缓存的加密材料的以下属性与材料请求相匹配。
以下工作流介绍了如何在缓存和不缓存数据密钥的情况下处理数据加密请求。这些工作流说明了如何在该过程中使用您创建的缓存组件,包括缓存和缓存 CMM。
加密数据而不进行缓存
获取加密材料而不缓存:
-
一个应用程序请求 AWS Encryption SDK加密数据。
该请求指定一个主密钥提供程序或密钥环。AWS Encryption SDK 创建一个与主密钥提供程序或密钥环交互的默认 CMM。
-
AWS Encryption SDK 请求 CMM 提供加密材料(获取加密材料)。
-
CMM 请求其密钥环(C 和 JavaScript)或主密钥提供程序(Java 和 Python)提供加密材料。这可能涉及调用一个加密服务,如 AWS Key Management Service (AWS KMS)。CMM 将加密材料返回给 AWS Encryption SDK。
-
AWS Encryption SDK使用明文数据密钥对数据进行加密。它在返回给用户的加密消息中存储加密数据和加密数据密钥。
![加密数据而不进行缓存](images/encrypt-workflow-no-cache.png)
使用缓存加密数据
获取加密材料并且缓存数据密钥:
-
一个应用程序请求 AWS Encryption SDK加密数据。
该请求指定了与底层加密材料管理器(CMM)关联的缓存加密材料管理器(缓存 CMM)。如果您指定主密钥提供程序或密钥环,AWS Encryption SDK 将创建默认的 CMM。
-
该开发工具包要求指定的缓存 CMM 提供加密材料。
-
缓存 CMM 从缓存中请求加密材料。
-
如果缓存找到匹配项,将更新匹配的缓存条目的期限和使用值,并将缓存的加密材料返回给缓存 CMM。
如果缓存条目符合其安全阈值,则缓存 CMM 将此条目返回到该开发工具包。否则,它通知缓存逐出该条目并继续操作,就好像没有匹配项一样。
-
如果缓存找不到有效的匹配项,缓存 CMM 将请求其基础 CMM 生成新的数据密钥。
基础 CMM 从其密钥环(C 和 JavaScript)或主密钥提供程序(Java 和 Python)获取加密材料。这可能涉及调用一个服务,如 AWS Key Management Service。基础 CMM 将数据密钥的明文和加密副本返回给缓存 CMM。
缓存 CMM 在缓存中保存新的加密材料。
-
-
缓存 CMM 将加密材料返回给 AWS Encryption SDK。
-
AWS Encryption SDK使用明文数据密钥对数据进行加密。它在返回给用户的加密消息中存储加密数据和加密数据密钥。
![加密数据并缓存数据密钥](images/encrypt-workflow-with-cache.png)
创建加密材料缓存
AWS Encryption SDK定义在数据密钥缓存中使用的加密材料缓存的要求。此外,缓存 CMM 还提供本地缓存,即可在内存中配置的最近最少使用(LRU)缓存LocalCryptoMaterialsCache
构造函数,在 JavaScript 中使用 getLocalCryptographicMaterialsCache 函数,或者在 C 中使用 aws_cryptosdk_materials_cache_local_new
构造函数。
本地缓存包含基本缓存管理逻辑,包括添加、驱逐和匹配缓存的条目以及维护缓存。您无需编写任何自定义缓存管理逻辑。您可以按原样使用本地缓存,对其进行自定义或替换任何兼容的缓存。
在创建本地缓存时,您可以设置其容量,即,该缓存可以保存的最大条目数。该设置有助于设计具有有限数据密钥重用次数的高效缓存。
AWS Encryption SDK for Java 和 AWS Encryption SDK for Python 还提供一个空的加密材料缓存 (NullCryptoMaterialsCache)。NullCryptoMaterialsCache 为所有 GET
操作返回未命中,并且不响应 PUT
操作。您可以在测试中使用 NullCryptoMaterialsCache,或者在包含缓存代码的应用程序中暂时禁用缓存。
在 AWS Encryption SDK 中,每个加密材料缓存都与缓存加密材料管理器(缓存 CMM)相关联。缓存 CMM 从缓存中获取数据密钥,将数据密钥放在缓存中,然后强制执行您设置的安全阈值。在创建缓存 CMM 时,您可以指定其使用的缓存以及生成其缓存的数据密钥的基础 CMM 或主密钥提供程序。
创建缓存加密材料管理器
要启用数据密钥缓存,您需要创建缓存和缓存加密材料管理器(缓存 CMM)。然后,在加密或解密数据的请求中指定缓存 CMM,而不是标准加密材料管理器(CMM)或主密钥提供程序或密钥环。
共有两种类型的 CMM。它们均获取数据密钥(和相关的加密材料),但使用不同的方法,如下所示:
-
CMM 与密钥环(C 或 JavaScript)或主密钥提供程序(Java 和 Python)关联。当开发工具包要求 CMM 提供加密或解密材料时,CMM 从其密钥环或主密钥提供程序获取材料。在 Java 和 Python 中,CMM 使用主密钥生成、加密或解密数据密钥。在 C 和 JavaScript 中,密钥环生成、加密和返回加密材料。
-
缓存 CMM 与一个缓存(例如本地缓存)和基础 CMM 相关联。在该开发工具包请求缓存 CMM 提供加密材料时,缓存 CMM 尝试从缓存中获取这些材料。如果找不到匹配项,缓存 CMM 将请求其基础 CMM 提供材料。然后,它在向调用方返回新的加密材料之前将其缓存。
缓存 CMM 还强制执行您为每个缓存条目设置的安全阈值。由于安全阈值是在缓存 CMM 中设置并由其强制执行的,所以您可以使用任何兼容的缓存,即使该缓存不是为敏感材料设计的。
在数据密钥缓存条目中包含哪些内容?
数据密钥缓存将数据密钥和相关的加密材料存储在缓存中。每个条目包含下面列出的元素。在决定是否使用数据密钥缓存功能以及在缓存加密材料管理器(缓存 CMM)上设置安全阈值时,您可能会发现该信息非常有用。
为加密请求缓存的条目
由于加密操作而添加到数据密钥缓存的条目包括以下元素:
为解密请求缓存的条目
由于解密操作而添加到数据密钥缓存的条目包括以下元素:
-
明文数据密钥
-
签名验证密钥(如果使用)
-
元数据,包括用于实施安全阈值的使用计数器
加密上下文:如何选择缓存条目
您可以在任何加密数据的请求中指定加密上下文。不过,加密上下文在数据密钥缓存中起到特殊的作用。该上下文允许在您的缓存中创建数据密钥子组,即使数据密钥来自于相同的缓存 CMM。
加密上下文是一组包含任意非机密数据的键值对。在加密期间,加密上下文以加密方式绑定到加密的数据,以便需要使用相同的加密上下文解密数据。在 AWS Encryption SDK中,加密上下文与加密的数据和数据密钥一起存储在加密的消息中。
在使用数据密钥缓存时,您还可以使用加密上下文为加密操作选择特定的缓存数据密钥。加密上下文与数据密钥一起保存在缓存条目中(它是缓存条目 ID 的一部分)。只有在加密上下文匹配时,才会重用缓存的数据密钥。如果要在加密请求中重用某些数据密钥,请指定相同的加密上下文。如果要避免使用这些数据密钥,请指定不同的加密上下文。
加密上下文始终是可选的,但建议使用。如果在请求中未指定加密上下文,则在缓存条目标识符中包含空加密上下文并与每个请求匹配。
我的应用程序是否使用缓存的数据密钥?
数据密钥缓存是一种优化策略,对于某些应用程序和工作负载是非常有效的。不过,由于它存在一些风险,请务必确定它对您的环境可能有多有效,然后确定收益是否大于风险。
由于数据密钥缓存重复使用数据密钥,因此,最明显的效果是减少了生成新数据密钥的调用次数。如果实施了数据密钥缓存,AWS Encryption SDK仅在缓存未命中时调用 AWS KMS GenerateDataKey
操作以创建初始数据密钥。但是,仅在生成大量具有相同特性(包括相同加密上下文和算法套件)的数据密钥的应用程序中,缓存才会显著提高性能。
要确定您的 AWS Encryption SDK实施是否实际使用缓存中的数据密钥,请尝试使用以下方法。
-
在主密钥基础设施的日志中,检查创建新数据密钥的调用频率。在数据密钥缓存有效时,创建新密钥的调用次数应明显减少。例如,如果您使用 AWS KMS 主密钥提供程序或密钥环,请搜索 CloudTrail 日志以查找 GenerateDataKey 调用。
-
比较 AWS Encryption SDK 为响应不同的加密请求而返回的加密消息。例如,如果您使用AWS Encryption SDK for Java,请比较来自不同加密调用的 ParsedCiphertext
对象。在 AWS Encryption SDK for JavaScript 中,比较 MessageHeader 的 encryptedDataKeys
属性的内容。在重复使用数据密钥时,加密消息中的加密数据密钥是完全相同的。