如何在BigQuery中使用KEYS.KEYSET_CHAIN解决密钥集反序列化失败问题
正确生成first_level_keyset的解决方案
你收到的AEAD.ENCRYPT failed: Keyset deserialization failed报错,核心原因是传入的FIRST_LEVEL_KEYSET不符合Tink库定义的、被指定KMS密钥加密的Keyset proto二进制规范,可通过以下两种方法生成符合要求的密钥集:
方法1:直接通过BigQuery内置函数生成(推荐)
不需要额外依赖,直接在BigQuery控制台运行以下SQL即可生成适配要求的密钥集:
DECLARE KMS_RESOURCE_NAME STRING DEFAULT 'gcp-kms://projects/XXX/locations/XXX/keyRings/XXX-key-ring/cryptoKeys/XXX-key'; -- 输出加密后一级密钥集的HEX编码 SELECT TO_HEX(KEYS.NEW_KEYSET(KMS_RESOURCE_NAME)) AS first_level_keyset_hex;
将查询输出的HEX字符串替换你原有代码中FROM_HEX("0a240... <suppressed>")里的内容即可正常使用。
方法2:通过Tink库本地生成
如果需要在本地生成密钥集,可使用Google Tink加密库操作,以下为Python示例:
- 提前给使用的服务账号授予对应KMS密钥的
cloudkms.cryptoKeyEncrypter权限 - 安装Tink依赖:
pip install tink google-cloud-kms - 运行以下代码:
import io import tink from tink import aead from tink.integration import gcpkms aead.register() # 替换为你的KMS密钥资源路径 KMS_KEY_URI = "gcp-kms://projects/XXX/locations/XXX/keyRings/XXX-key-ring/cryptoKeys/XXX-key" # 替换为你的服务账号密钥文件路径,使用应用默认凭证可省略该参数 CRED_PATH = "./service-account.json" # 初始化KMS客户端 kms_client = gcpkms.GcpKmsClient(key_uri=KMS_KEY_URI, credentials_path=CRED_PATH) kms_aead = kms_client.get_aead(KMS_KEY_URI) # 生成AES256-GCM类型的明文一级密钥集 keyset_handle = tink.new_keyset_handle(aead.aead_key_templates.AES256_GCM) # 用KMS密钥加密一级密钥集 encrypted_keyset_buf = io.BytesIO() writer = tink.BinaryKeysetWriter(encrypted_keyset_buf) keyset_handle.write(writer, kms_aead) # 输出HEX编码的加密密钥集 print("first_level_keyset_hex:", encrypted_keyset_buf.getvalue().hex())
将代码输出的HEX字符串传入你原有代码的FROM_HEX方法即可。
注意:
- 生成密钥集时使用的KMS密钥,必须和
KEYS.KEYSET_CHAIN中传入的KMS资源路径完全一致,否则会无法解密密钥集导致报错- 不要修改生成的HEX字符串的任意字符,任何篡改都会导致Keyset proto解析失败
内容的提问来源于stack exchange,提问作者Edmilson Santana
相关产品推荐
相关产品推荐

