Google Cloud KMS: 字段 ciphertext_crc32c 中的校验和与字段密文中的数据不匹配

Google Cloud KMS: The checksum in field ciphertext_crc32c did not match the data in field ciphertext

我在设置系统以在我的 Node.js 后端加密和解密数据时遇到问题。我正在关注 this guide 的过程。

我写了一个助手 class KMSEncryption 来抽象示例中的逻辑。这是我调用它的代码:

const kms = new KMSEncryption();
const textToEncrypt = 'hello world!';
const base64string = await kms.encrypt(textToEncrypt);
const decrypted = await kms.decrypt(base64string);

我遇到的问题是解密失败并出现以下错误:

UnhandledPromiseRejectionWarning: Error: 3 INVALID_ARGUMENT: The checksum in field ciphertext_crc32c did not match the data in field ciphertext.

我试图与 Google 文档中的指南并排比较,但我看不出哪里出错了。

我尝试过的一些事情包括:

感谢任何帮助。谢谢

我相信你是用base64对密文进行编码的:

        if (typeof ciphertext !== 'string') {
            return this.toBase64(ciphertext);
        }

但是您在计算 crc32c 之前没有反转编码。

我从示例代码中提取了这个示例,它在 Cloud Shell 中对我来说工作正常。 (不好意思弄乱了):

// On Cloud Shell, install ts first with:
//   npm install -g typescript
//   npm i @types/node
//   npm i @google-cloud/kms
//   npm i fast-crc32c
// Then to compile and run:
//   tsc testcrc.ts && node testcrc.js

// Code adapted from https://cloud.google.com/kms/docs/encrypt-decrypt#kms-decrypt-symmetric-nodejs

const projectId = 'kms-test-1367';
const locationId = 'global';
const keyRingId = 'so-67778448';
const keyId = 'example';
const plaintextBuffer = Buffer.from('squeamish ossifrage');

// Imports the Cloud KMS library
const {KeyManagementServiceClient} = require('@google-cloud/kms');

const crc32c = require('fast-crc32c');

// Instantiates a client
const client = new KeyManagementServiceClient();

// Build the key name
const keyName = client.cryptoKeyPath(projectId, locationId, keyRingId, keyId);

// Optional, but recommended: compute plaintext's CRC32C.
async function encryptSymmetric() {
  const plaintextCrc32c = crc32c.calculate(plaintextBuffer);
  console.log(`Plaintext crc32c: ${plaintextCrc32c}`);
  const [encryptResponse] = await client.encrypt({
    name: keyName,
    plaintext: plaintextBuffer,
    plaintextCrc32c: {
      value: plaintextCrc32c,
    },
  });

  const ciphertext = encryptResponse.ciphertext;

  // Optional, but recommended: perform integrity verification on encryptResponse.
  // For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
  // https://cloud.google.com/kms/docs/data-integrity-guidelines
  if (!encryptResponse.verifiedPlaintextCrc32c) {
    throw new Error('Encrypt: request corrupted in-transit');
  }
  if (
    crc32c.calculate(ciphertext) !==
    Number(encryptResponse.ciphertextCrc32c.value)
  ) {
    throw new Error('Encrypt: response corrupted in-transit');
  }

  console.log(`Ciphertext: ${ciphertext.toString('base64')}`);
  console.log(`Ciphertext crc32c: ${encryptResponse.ciphertextCrc32c.value}`)
  return ciphertext;
}

async function decryptSymmetric(ciphertext) {
  const cipherTextBuf = Buffer.from(await ciphertext);
  const ciphertextCrc32c = crc32c.calculate(cipherTextBuf);
  console.log(`Ciphertext crc32c: ${ciphertextCrc32c}`);
  const [decryptResponse] = await client.decrypt({
    name: keyName,
    ciphertext: cipherTextBuf,
    ciphertextCrc32c: {
      value: ciphertextCrc32c,
    },
  });

  // Optional, but recommended: perform integrity verification on decryptResponse.
  // For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
  // https://cloud.google.com/kms/docs/data-integrity-guidelines
  if (
    crc32c.calculate(decryptResponse.plaintext) !==
    Number(decryptResponse.plaintextCrc32c.value)
  ) {
    throw new Error('Decrypt: response corrupted in-transit');
  }

  const plaintext = decryptResponse.plaintext.toString();

  console.log(`Plaintext: ${plaintext}`);
  console.log(`Plaintext crc32c: ${decryptResponse.plaintextCrc32c.value}`)
  return plaintext;
}

decryptSymmetric(encryptSymmetric());

你可以看到它多次记录了crc32c。示例字符串“squeamish ossifrage”的正确 crc32c 是 870328919。密文的 crc32c 将在每个 运行.

上变化

自己运行这段代码,你只需要指向你的项目,区域,密钥环,密钥(应该是对称加密密钥)即可;希望将此代码与您的代码结果进行比较将帮助您找到问题所在。

感谢使用 Google Cloud 和 Cloud KMS!