如何解决Firebase Cloud Function调用Cloud KMS时的ERROR 13问题
Firebase Cloud Function调用Cloud KMS出现ERROR 13的解决方法
问题核心
你的云函数调用Cloud KMS时触发ERROR 13 INTERNAL: Request message serialization failure: invalid encoding,主要由两个代码问题导致:
1. KMS密钥路径构造参数顺序错误
KeyManagementServiceClient.keyRingPath()的参数顺序不符合官方要求,正确顺序应为:projectId, locationId, keyRingId。你当前代码把locationId放在首位,且注释掉了projectId,导致生成的密钥资源名称格式完全错误,引发gRPC序列化失败。
2. 明文数据类型不符合要求
Cloud KMS的encrypt接口要求plaintext参数必须是Buffer二进制类型,直接传入字符串会导致编码解析异常,触发"invalid encoding"错误。
修正后的完整代码
const functions = require("firebase-functions"); const {KeyManagementServiceClient} = require("@google-cloud/kms"); const projectId = "my-project-id"; // 取消注释并填入你的项目ID const locationId = "europe-west1"; const keyring = "my-keyring-name"; const key = "my-key-name"; const client = new KeyManagementServiceClient(); /** * 用Cloud KMS加密明文 * @param {string} plaintext 待加密的明文字符串 * @return {Promise<string>} 加密后的Base64字符串 */ async function encryptPassword(plaintext) { // 构造正确的密钥资源路径 const keyName = client.cryptoKeyPath(projectId, locationId, keyring, key); const request = { name: keyName, // 将字符串转为Buffer类型 plaintext: Buffer.from(plaintext), }; const [response] = await client.encrypt(request); // 将返回的Buffer转为Base64字符串,方便存入Firestore return response.ciphertext.toString("base64"); } exports.passwordAdded = functions.firestore.document("/accounts/{documentId}") .onCreate(async (snapshot, context) => { const account = snapshot.data(); // 加密哈希后的密码 const encryptedPassword = await encryptPassword(account.hashedPassword); // 更新文档存储加密后的密码 await snapshot.ref.update({hashedPassword: encryptedPassword}); });
关键修正说明
- 密钥路径: 使用
cryptoKeyPath()替代keyRingPath()(因为你需要的是具体加密密钥的路径,而非密钥环路径),并传入正确的projectId参数,确保资源名称格式符合Google Cloud规范。 - 数据类型转换: 将待加密的字符串通过
Buffer.from()转为二进制类型,同时将KMS返回的加密结果(Buffer)转为Base64字符串,Firestore支持存储Base64格式的字符串。 - 返回值处理: 解构
client.encrypt()的返回值(它返回的是数组,第一个元素是响应对象),避免获取错误的属性。
内容的提问来源于stack exchange,提问作者Leonard
相关产品推荐
相关产品推荐

