0

我正在尝试从 AWS S3 迁移到 Azure Blob 存储,但在生成客户提供的加密密钥时遇到了一些问题。作为参考,在 AWS 中,可以毫不费力地启用服务器端加密(AWS Server-Side Encryption)。在 Azure 中,同样应该可以使用 CustomerProvidedEncryptionKey。

Microsoft 创建 CustomerProvidedEncryptionKey 的要求如下(Microsoft Docs on CPK):

key_value: str (Required)
Base64-encoded AES-256 encryption key value.

key_hash: str (Required)
Base64-encoded SHA256 of the encryption key.

但是,当我创建任何 32 个字符长的 AES256 加密密钥和它的 SHA256 哈希时,无论我如何生成或编码它们,我都无法让 python SDK 接受它们。

到目前为止我的工作:

import hashlib
import base64
from azure.storage.blob import (
    ContainerClient,
    __version__,
    CustomerProvidedEncryptionKey,
)
import os

local_file_name = "sample.txt"
target_file_name = "sample-encrypted.txt"
container_name = "test"
connection_str = "<redacted>"

# Key and its Hash
key_value = b"32byteslongsecretkeyshallbegiven"
key_hash = hashlib.sha256(key_value).hexdigest().encode()

# Encode the key and its hash into base64
key_value_encoded = base64.b64encode(key_value)
key_hash_encoded = base64.b64encode(key_hash)

# Create cpk object to provide to Azure
cpk = CustomerProvidedEncryptionKey(key_value_encoded, key_hash_encoded)

# Create the BlobServiceClient object which will be used to create a container client
container_client = ContainerClient.from_connection_string(
    connection_str,
    container_name=container_name,
)

# Upload the blob
with open(local_file_name, "rb") as data:
    container_client.upload_blob(
        data=data, name=target_file_name, overwrite=True, cpk=cpk
    )

这将失败并显示以下消息:

ErrorCode:InvalidHeaderValue
headername:x-ms-encryption-key
headervalue:b'MzJieXRlc2xvbmdzZWNyZXRrZXlzaGFsbGJlZ2l2ZW4='

只有在使用微软为 SDK 创建的测试用例中的硬编码密钥和哈希值(带有硬编码密钥的 Azure SDK 测试用例)时,我才能使用客户端提供的密钥进行服务器端加密。

TEST_ENCRYPTION_KEY = CustomerProvidedEncryptionKey(
key_value="MDEyMzQ1NjcwMTIzNDU2NzAxMjM0NTY3MDEyMzQ1Njc=",
key_hash="3QFFFpRA5+XANHqwwbT4yXDmrT/2JaLt/FKHjzhOdoE="
)

请注意,它们的硬编码键值和键散列长度为 44 个字符,这意味着在这种情况下,它是一个 32 个字符的字符串,编码为 base64。这对散列很奇怪,因为真正的 SHA256 散列有 64 个字符长,在 base64 中编码时会更长。这意味着使用了一些其他(未知)散列算法来生成key_hash.

如果我在上面的代码片段中没有提供密钥,则上传成功,如果我提供硬编码密钥及其哈希,则上传成功并已加密。但是,我找不到任何方法来生成密钥及其哈希以成功上传和加密任何 blob。

任何方向将不胜感激!

4

1 回答 1

0

代码片段的问题是密钥哈希的编码。由于哈希的 hexdigest 是一个表示十六进制字符串的 python 字符串对象,因此我们必须特别注意对其进行解码并将其类型视为十六进制。此外,我们必须将 base64 编码的字符串重新编码为 python 字符串对象,然后再将其传递给 CustomerProvidedEncryptionKey。

有关完整的工作代码,请参阅https://gist.github.com/CodyRichter/a18c293d80c9dd71a3905bf9c44e377f

于 2021-10-21T22:44:34.800 回答