无法生成 Azure CustomerProvidedEncryptionKey (cpk)
Unable To Generate Azure CustomerProvidedEncryptionKey (cpk)
我正在尝试从 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 Case with hardcoded key).
TEST_ENCRYPTION_KEY = CustomerProvidedEncryptionKey(
key_value="MDEyMzQ1NjcwMTIzNDU2NzAxMjM0NTY3MDEyMzQ1Njc=",
key_hash="3QFFFpRA5+XANHqwwbT4yXDmrT/2JaLt/FKHjzhOdoE="
)
请注意,它们的硬编码键值和键哈希长度为 44 个字符,这意味着在本例中它是一个编码为 base64 的 32 个字符的字符串。这对哈希值很奇怪,因为真正的 SHA256 哈希值有 64 个字符长,如果用 base64 编码的话会更长。这意味着使用了其他一些(未知的)哈希算法来生成 key_hash
.
如果我在上面的代码片段中没有提供密钥,则上传成功,如果我提供硬编码密钥及其散列,则上传成功并被加密。但是,我找不到任何方法来生成密钥及其哈希值以成功上传和加密任何 blob。
任何方向将不胜感激!
代码片段的问题在于密钥散列的编码。由于哈希的 hexdigest 是一个 python 表示十六进制字符串的字符串对象,因此我们必须特别注意对其进行解码并将其类型视为十六进制。此外,我们必须将 base64 编码的字符串重新编码为 python 字符串对象,然后再将其传递给 CustomerProvidedEncryptionKey。
有关完整的工作代码,请参阅 https://gist.github.com/CodyRichter/a18c293d80c9dd71a3905bf9c44e377f
我正在尝试从 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 Case with hardcoded key).
TEST_ENCRYPTION_KEY = CustomerProvidedEncryptionKey(
key_value="MDEyMzQ1NjcwMTIzNDU2NzAxMjM0NTY3MDEyMzQ1Njc=",
key_hash="3QFFFpRA5+XANHqwwbT4yXDmrT/2JaLt/FKHjzhOdoE="
)
请注意,它们的硬编码键值和键哈希长度为 44 个字符,这意味着在本例中它是一个编码为 base64 的 32 个字符的字符串。这对哈希值很奇怪,因为真正的 SHA256 哈希值有 64 个字符长,如果用 base64 编码的话会更长。这意味着使用了其他一些(未知的)哈希算法来生成 key_hash
.
如果我在上面的代码片段中没有提供密钥,则上传成功,如果我提供硬编码密钥及其散列,则上传成功并被加密。但是,我找不到任何方法来生成密钥及其哈希值以成功上传和加密任何 blob。
任何方向将不胜感激!
代码片段的问题在于密钥散列的编码。由于哈希的 hexdigest 是一个 python 表示十六进制字符串的字符串对象,因此我们必须特别注意对其进行解码并将其类型视为十六进制。此外,我们必须将 base64 编码的字符串重新编码为 python 字符串对象,然后再将其传递给 CustomerProvidedEncryptionKey。
有关完整的工作代码,请参阅 https://gist.github.com/CodyRichter/a18c293d80c9dd71a3905bf9c44e377f