如何在Azure Data Factory中使用客户公钥加密文件并存入Blob存储?
可行实现方案
一、区分两个加密层级
首先明确你提到的两个加密需求:
- 文件级PGP加密:用你持有的公钥对文件内容进行加密,确保只有持有对应私钥的接收方可以解密。
- Blob存储静态加密(客户管理密钥):Azure Blob存储用你指定的客户管理密钥对存储的数据进行静态加密,这部分不需要你持有私钥,只需在Azure Key Vault中配置密钥并关联到存储账户即可。
二、Blob存储静态加密(客户管理密钥)配置
这部分是Azure原生支持的操作,无需依赖ADF:
- 在Azure Key Vault中创建或导入客户管理的RSA密钥。
- 给Blob存储账户授予访问该Key Vault密钥的权限(通过访问策略或RBAC)。
- 在Blob存储账户的加密设置中,选择“客户管理的密钥”,关联Key Vault中的目标密钥。
完成后,所有存入该存储账户的Blob都会自动用这个客户管理密钥进行静态加密,和你是否持有私钥无关。
三、文件级PGP加密(ADF实现)
ADF没有内置的PGP加密活动,需通过自定义活动实现,以下两种方案可选:
方案1:自定义Python活动(推荐)
前提条件
- 部署自托管集成运行时(托管集成运行时无法自定义环境,需在自托管节点安装依赖)。
- 在自托管运行时所在机器上安装:
Python 3.x+python-gnupg库(执行pip install python-gnupg)。 - 将PGP公钥存储在Azure Key Vault中,通过ADF的密钥保管库链接服务访问。
Python加密脚本示例
import gnupg import os from azure.storage.blob import BlobServiceClient # 从ADF活动参数获取配置 source_blob_url = os.environ.get('SOURCE_BLOB_URL') target_container_name = os.environ.get('TARGET_CONTAINER') target_blob_name = os.environ.get('TARGET_BLOB_NAME') pgp_public_key = os.environ.get('PGP_PUBLIC_KEY') storage_connection_string = os.environ.get('STORAGE_CONNECTION_STRING') # 初始化GPG并导入公钥 gpg = gnupg.GPG() import_result = gpg.import_keys(pgp_public_key) if not import_result.fingerprints: raise Exception("Failed to import PGP public key") recipient_fingerprint = import_result.fingerprints[0] # 下载源文件到本地临时路径 temp_source_path = f"/tmp/{os.path.basename(source_blob_url)}" blob_service_client = BlobServiceClient.from_connection_string(storage_connection_string) source_blob_client = blob_service_client.get_blob_client( container=source_blob_url.split('/')[3], blob='/'.join(source_blob_url.split('/')[4:]) ) with open(temp_source_path, "wb") as f: data = source_blob_client.download_blob() data.readinto(f) # 加密文件 temp_encrypted_path = f"{temp_source_path}.gpg" with open(temp_source_path, "rb") as f: status = gpg.encrypt_file(f, recipients=[recipient_fingerprint], output=temp_encrypted_path) if not status.ok: raise Exception(f"PGP encryption failed: {status.stderr}") # 上传加密后的文件到目标Blob target_blob_client = blob_service_client.get_blob_client(container=target_container_name, blob=target_blob_name) with open(temp_encrypted_path, "rb") as f: target_blob_client.upload_blob(f, overwrite=True) # 清理临时文件 os.remove(temp_source_path) os.remove(temp_encrypted_path)
ADF配置步骤
- 创建自定义活动,选择自托管集成运行时。
- 在活动“设置”中,指定Python脚本的存储路径(如Blob存储中的脚本文件)。
- 在“参数”中传递变量:
SOURCE_BLOB_URL、TARGET_CONTAINER、TARGET_BLOB_NAME、PGP_PUBLIC_KEY(从Key Vault获取的密钥值)、STORAGE_CONNECTION_STRING(存储账户连接字符串)。
方案2:自定义Shell活动
前提条件
- 自托管集成运行时所在机器安装
gpg工具。 - 将PGP公钥导入到运行时机器的gpg密钥环(执行
gpg --import public_key.asc),或在脚本中临时导入。
Shell脚本示例
#!/bin/bash # 从ADF参数获取变量 SOURCE_BLOB_URL=$1 TARGET_CONTAINER=$2 TARGET_BLOB_NAME=$3 PGP_KEY_ID=$4 STORAGE_CONNECTION_STRING=$5 # 下载源文件到本地 az storage blob download \ --connection-string "$STORAGE_CONNECTION_STRING" \ --container-name $(echo $SOURCE_BLOB_URL | cut -d'/' -f4) \ --name $(echo $SOURCE_BLOB_URL | cut -d'/' -f5-) \ --file /tmp/source_file # PGP加密文件 gpg --output /tmp/encrypted_file.gpg --recipient $PGP_KEY_ID --encrypt /tmp/source_file # 上传加密文件到Blob az storage blob upload \ --connection-string "$STORAGE_CONNECTION_STRING" \ --container-name $TARGET_CONTAINER \ --name $TARGET_BLOB_NAME \ --file /tmp/encrypted_file.gpg # 清理临时文件 rm /tmp/source_file /tmp/encrypted_file.gpg
ADF配置步骤
- 创建自定义活动,选择自托管集成运行时。
- 指定Shell脚本路径,在“命令”中传递对应参数(脚本中的$1-$5)。
- 确保自托管运行时安装了Azure CLI(用于Blob上传下载),或改用
curl访问Blob SAS URL。
关键注意事项
- 自托管集成运行时权限:需确保运行时服务账户有权限访问源Blob、目标Blob以及Key Vault(若读取公钥)。
- 公钥安全:避免在脚本或参数中硬编码公钥,通过Key Vault托管并由ADF动态获取。
- 错误处理:在脚本中添加日志和错误捕获逻辑,便于ADF监控活动执行状态。
内容的提问来源于stack exchange,提问作者Alfred Masri
相关产品推荐
相关产品推荐

