这是我的第一个堆栈溢出问题!
无论如何,我正在尝试使用Cloud KMS为我在App Engine中运行的Node API设置DB连接秘密的解密。为了使其正常工作,我一直在本地进行测试。我使用gcloud CLI加密了机密,然后将其上载到Cloud Storage存储桶(如果重要的话,可以使用与API不同的项目)。在API中提取加密的机密很好,但是当我尝试解密这些机密时,我得到了:
Error: 3 INVALID_ARGUMENT: Decryption failed: verify that 'name' refers to the correct CryptoKey.
我检查并重新检查我是否具有正确的项目ID,密钥环ID,密钥ID。
在上传到存储桶之前,我曾尝试在base64中对加密的机密进行编码。我尝试对API中的编码和加密机密进行硬编码。这些都不起作用。
因此,仅出于完整性检查的目的,我重新编写了代码以对字符串进行简单加密,然后使用相同的cryptoKeyPath对API进行解密。加密似乎可以正常工作,但是在解密过程中仍然出现上述错误。
(某些Cloud Storage代码仍然存在,但直到弄清楚解密后才使用)。
const Storage = require('@google-cloud/storage');
console.log(process.env.GOOGLE_APPLICATION_CREDENTIALS);
// if running in production we need to get the .env file from a storage bucket and decrypt.
const addSecretsToEnv = async () => {
// setup for storage bucket
const bucketName=<bucketName>;
const fileName=<fileName>;
const storage = new Storage.Storage();
const file = storage.bucket(bucketName).file(fileName);
// setup for KMS
const client = new kms.KeyManagementServiceClient();
const locationId = 'global';
const projectId = <projectId>;
const keyRingID = <keyRingID>;
const keyID = <keyID>;
try {
const formattedName = client.cryptoKeyPath(
projectId,
locationId,
keyRingID,
keyID,
);
const [result] = await client.encrypt({
name: formattedName,
plainText: 'help me!!!'
});
console.log(typeof result);
console.log(result);
const cipherText = result.ciphertext;
console.log(typeof cipherText);
console.log(cipherText);
const [decrypted] = await client.decrypt({
name: formattedName,
cipherText,
});
console.log(decrypted);
} catch(error) {
console.log(error);
}
}
module.exports = {
addSecretsToEnv
};
我通过GOOGLE_APPLICATION_CREDENTIALS env变量设置了身份验证,该变量指向具有Cloud KMS CryptoKey Encrypter / Decrypter和Cloud KMS Admin角色(无奈地添加了admin角色)的服务帐户的JSON密钥文件。 / p>
有人可以帮我吗?
谢谢。
答案 0 :(得分:0)
大写字母T
是您的罪魁祸首。在Node中,没有值的键将扩展为它们的对象名称。例如,给定:
let foo = "banana";
将foo
传递到这样的对象中:
doTheThing({ foo });
扩展为:
doTheThing({ foo: foo }); // which is { foo: "banana" }
使用plainText
或cipherText
时,它们在Node对象中分别扩展为{plainText: "..."}
和{cipherText: "..."}
。不幸的是,那些不是公认的字段,但是它们被默默地忽略了。因此,有效地您没有将任何纯文本或密文传递给任何API调用。
对空字符串进行加密 是有效的,但对空字符串进行解密则无效。这就是为什么您在加密时没有收到错误的原因。
要解决此问题,请将plainText
和cipherText
分别替换为plaintext
和ciphertext
。我个人建议您改为明确声明该函数的参数调用:
const [decrypted] = await client.decrypt({
name: "projects/p/...",
ciphertext: myCiphertext,
});
否则,对变量进行微妙的重命名会以非常晦涩的方式彻底破坏代码。