本页面讨论了客户提供的加密密钥。如需了解其他加密选项,请参阅数据加密选项。
概览
作为标准 Cloud Storage 加密之上的附加层,您可以选择提供自己的 AES-256 加密密钥(采用标准 Base64 编码)。此密钥被称为客户提供的加密密钥。如果您提供客户提供的加密密钥,则 Cloud Storage 不会将您的密钥永久存储在其服务器中或以其他方式管理您的密钥。
相反,您将为每个 Cloud Storage 操作提供密钥,操作完成后,系统将从 Cloud Storage 服务器中完全清除您的密钥。Cloud Storage 仅存储密钥的加密哈希值,以便根据哈希值验证未来的请求。您的密钥将无法从此哈希值中恢复,并且此哈希值无法用于解密您的数据。
我们建议您将每个密钥备份到安全位置,并采取预防措施来确保密钥不会与不受信任方共享。如果存放加密密钥的任何文件或机器遭到破解,您应立即对使用被破解的密钥加密的所有对象执行密钥轮替。
何时使用密钥?
将客户提供的加密密钥应用到对象上时,Cloud Storage 会在加密以下信息时使用该密钥:
- 对象的数据。
- 对象的 CRC32C 校验和。
- 对象的 MD5 哈希值。
标准 Cloud Storage 加密用于加密对象的其余元数据,包括对象的名称。这样您可以读取和更新常规元数据以及列出、覆盖和删除对象,无需使用客户提供的加密密钥。但是,要执行以上任一操作,您必须具有足够的权限。
例如,如果对象是使用客户提供的加密密钥进行加密的,您必须使用该密钥才能在该对象上执行操作,例如下载或移动对象。如果您尝试在不提供密钥的情况下读取对象的元数据,您会收到对象名称和 Content-Type
之类的元数据,但不会收到对象的 CRC32C 校验和或 MD5 哈希值。如果在针对对象元数据的请求中提供了密钥,则除了收到元数据以外,您还将收到对象的 CRC32C 校验和以及 MD5 哈希值。
重写行为
如果您重写使用客户提供的加密密钥加密的对象,但未提供用于加密重写对象的密钥,则会发生以下情况:
如果您在请求中包含适当的解密密钥,则重写的对象将使用目标存储桶的默认 Cloud Key Management Service 加密密钥进行加密,或者如果缺少此类密钥,则由标准 Cloud Storage 加密进行加密。
如果您没有在请求中添加适当的解密密钥,则会收到错误。
HTTPS 检查
如需在读取和写入操作期间保护通过互联网传输的数据,请使用传输层安全协议(通常称为 TLS 或 HTTPS)。提供加密密钥时需要 TLS。如果您意外地通过未加密的 (HTTP) 连接使用加密密钥,攻击者可能会拦截您的密钥。由于存在这种可能性,Cloud Storage API 会返回一条错误消息,警告您密钥可能已泄露。如果发生这种情况,您应立即轮替密钥
限制
使用客户提供的加密密钥时,存在以下限制:
您无法使用 Google Cloud 控制台下载使用客户提供的加密密钥加密的对象。同样,如果您使用 Google Cloud 控制台上传对象,则无法使用客户提供的加密密钥加密对象。
Storage Transfer Service 和 Cloud Dataflow 不支持使用客户提供的加密密钥加密的对象。
您只能在单个对象上设置客户提供的加密密钥。 您无法为存储桶设置默认的客户提供的加密密钥。
如果对象通过客户提供的加密密钥进行加密,并且您要对此对象执行
compose
操作,则必须使用相同的密钥对组件对象进行加密,并且您需要随同组合请求一起提供该密钥。生成的复合对象将使用相同的密钥进行加密。传送使用客户提供的加密密钥加密的对象时,Cloud Storage 会忽略与该对象关联的
Cache-Control
元数据,并通过将Cache-Control
设置为private, max-age=0
来传送该对象。
通过 REST API 使用加密密钥
当您使用客户提供的加密密钥并直接使用 JSON 或 XML API 时,您必须同时提供 AES-256 密钥和该密钥的 SHA256 哈希值。您应安全存储 AES-256 密钥和密钥的 SHA256 哈希值。Cloud Storage 将密钥的 SHA256 哈希值存储在对象的元数据中,以便您未来进行检索。Cloud Storage(或其他任何人)无法使用此 SHA256 哈希值来解密您的数据。之所以存储此哈希值,目的是为了唯一标识用于加密特定对象的 AES-256 密钥。
请求标头
在 JSON 或 XML 请求中包含以下 HTTP 标头:
标头名称 | 值 | 说明 |
---|---|---|
x-goog-encryption-algorithm |
字符串 | 要使用的加密算法。您必须使用值 AES256 。 |
x-goog-encryption-key |
字符串 | AES-256 加密密钥的 RFC 4648 Base64 编码字符串。 |
x-goog-encryption-key-sha256 |
字符串 | 加密密钥的 SHA256 哈希值的 RFC 4648 Base64 编码字符串。 |
如果您使用 JSON API 执行重写操作,则使用上面列出的标头加密目标对象,并使用以下标头解密源对象:
标头名称 | 值 | 说明 |
---|---|---|
x-goog-copy-source-encryption-algorithm |
字符串 | 要使用的加密算法。您必须使用值 AES256 。 |
x-goog-copy-source-encryption-key |
字符串 | 源对象的 AES-256 加密密钥的 RFC 4648 Base64 编码字符串。 |
x-goog-copy-source-encryption-key-sha256 |
字符串 | 源对象的加密密钥的 SHA256 哈希值的 RFC 4648 Base64 编码字符串。 |
响应
JSON
使用 JSON API 时,响应正文将返回客户提供的加密密钥的元数据,其中包括以下属性:
属性名称 | 值 | 说明 |
---|---|---|
customerEncryption |
对象 | 用于请求的加密的相关信息。 |
customerEncryption.encryptionAlgorithm |
字符串 | 使用的加密算法。始终包含值 AES256 。 |
customerEncryption.keySha256 |
字符串 | 加密密钥的 SHA256 哈希值的 RFC 4648 Base64 编码字符串。您可以使用此 SHA256 哈希值来唯一标识解密对象所需的 AES-256 加密密钥(您必须安全存储该密钥)。 |
XML
使用 XML API 时,响应中包含以下标头:
标头名称 | 值 | 说明 |
---|---|---|
x-goog-encryption-algorithm |
字符串 | 使用的加密算法。始终包含值 AES256 。 |
x-goog-encryption-key-sha256 |
字符串 | 加密密钥的 SHA256 哈希值的 RFC 4648 Base64 编码字符串。您可以使用此 SHA256 哈希值来唯一标识解密对象所需的 AES-256 加密密钥(您必须安全存储该密钥)。 |
在以下情况下,您收到 HTTP 400 错误:
- 您使用客户提供的加密密钥上传对象,并尝试在不提供密钥的情况下对对象执行其他操作(用于请求或更新大多数元数据或删除对象的操作除外)。
- 您使用客户提供的加密密钥上传对象,并尝试使用错误的密钥对对象执行其他操作。
- 您在不提供客户提供的加密密钥的情况下上传对象,并尝试使用客户提供的加密密钥对该对象执行其他操作。
- 您指定了无效的加密算法、密钥或 SHA256 哈希值。
加密密钥和 gcloud storage
Google Cloud CLI 支持使用客户提供的加密密钥。将 gcloud CLI 与客户提供的加密密钥搭配使用时,请注意以下事项:
在命令中指定为加密密钥的密钥在命令中均用作加密密钥,并根据需要用作解密密钥。
您可以选择最多指定 100 个解密密钥,这些密钥仅用于解密对象。
解密时,系统会计算任何提供的加密和解密密钥的 SHA256 哈希值,并通过匹配对象元数据中的 SHA256 哈希值来选择适用于特定对象的正确密钥。
为现有对象添加或轮替客户提供的加密密钥时,该对象会被重写为请求的一部分。即使对于
gcloud storage objects update
命令也是如此。列出可以为使用客户提供的密钥加密的对象返回 MD5 或 CRC32C 哈希的命令,对每个此类对象执行额外的元数据
GET
请求。与列出使用标准 Cloud Storage 加密方法加密的对象相比,这些额外的请求可能会大大降低列出的速度。如果加密密钥在部分完成的写入或复制操作期间可以或确实会更改,例如,您在强制退出或遇到网络超时后重新运行
cp
上传时,操作重启以确保目标对象是使用新密钥写入的。
加密密钥轮替
如果对象是使用客户提供的加密密钥进行加密的,您可以通过重写对象来轮替对象的密钥。JSON API 支持重写操作,XML API 不支持。要查看密钥轮替的示例,请参阅轮替加密密钥。
后续步骤
- 了解如何使用客户提供的加密密钥。