如何使用 Google Cloud 的 Cloud KMS 存储私钥?

How do I store a private key using Google Cloud's Cloud KMS?

我一直在尝试阅读文档并观看他们的一些视频,但我并不完全清楚如何使用 GCP 的 Cloud KMS 存储私钥。

我的想法是把私钥存储在存储中,然后使用Cloud KMS加密吗?我怎样才能让这个密钥作为我的应用程序的秘密可用?

我知道这是一个非常基本的问题,但我找不到关于如何做到这一点的简单分解 - 我正在寻找关于这个概念的简单解释。谢谢!

请自己阅读:https://cloud.google.com/kms/docs ...也许您会想出一个更有针对性的问题。而且我认为有一点误解 - 你只能在服务器端检索这些,而不能在客户端检索(否则客户端需要拥有服务帐户的 RSA 私钥,该私钥可以访问Cloud KMS,这本身就是一个安全漏洞)。所以这通常只对 a) 服务器端应用程序和 b) 例如有用。 Google 云构建。

通常必须:

  1. 使用 gcloud kms keyrings create

    创建密钥环
  2. 使用 gcloud kms keys create

    创建密钥
  3. 然后使用gcloud kms encrypt and gcloud kms decrypt

我还可以提供一个 usage example(它假设有一个带钥匙的钥匙圈)。 只是为了表明,不一定要设置秘密。 gcloud kms 可以很好地提供构建秘密 - 假设可以使用具有角色 roles/cloudkms.cryptoKeyEncrypterDecrypter 的服务帐户。给定的示例解密各种构建秘密 - 无需处理元数据中的任何 base64 编码二进制文件(这是一种解决方法,而不是实际解决方案)。

这是在 Google 云平台 (GCP) 上存储私钥的高级描述:

我最终使用了 Google KMS,特别是 asymmetric encryption 功能。

创建非对称密钥的一般步骤是:

  • 在您的项目中创建密钥环
  • 创建一个具有 ENCRYPT_DECRYPT 目的的密钥(如果像我一样,您正在尝试使用 Terraform 执行此操作,则有一些 documentation here

创建密钥后,我们现在可以使用我们在上一步中创建的非对称密钥中的 public 密钥来加密一些我们想要保护的数据。

重要的是要注意,对于非对称密钥,有一个 public-私钥对,我们从不处理私钥(即只有 GCP 知道私钥)。

以下是从本地计算机加密某些数据的方法:

echo -n my-secret-password | gcloud kms encrypt \
> --project my-project \
> --location us-central1 \
> --keyring my-key-ring \
> --key my-crypto-key \
> --plaintext-file - \
> --ciphertext-file - \
> | base64

这将输出一些base64编码的密文,例如:

CiQAqD+xX4SXOSziF4a8JYvq4spfAuWhhYSNul33H85HnVtNQW4SOgDu2UZ46dQCRFl5MF6ekabviN8xq+F+2035ZJ85B+xTYXqNf4mZs0RJitnWWuXlYQh6axnnJYu3kDU=

然后需要将此密文作为秘密存储。一旦存储为秘密,我们需要在我们的应用程序代码中执行以下操作,以便将密文解密为可用格式。

下面是使用@google-cloud/kms模块解密密文的例子:https://cloud.google.com/kms/docs/hsm#kms-decrypt-symmetric-nodejs

在 Nodejs 中是这样的:

//
// TODO(developer): Uncomment these variables before running the sample.
//
// const projectId = 'my-project';
// const locationId = 'us-east1';
// const keyRingId = 'my-key-ring';
// const keyId = 'my-key';
// Ciphertext must be either a Buffer object or a base-64 encoded string
// const ciphertext = Buffer.from('...');

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

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

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

// Optional, but recommended: compute ciphertext's CRC32C.
const crc32c = require('fast-crc32c');
const ciphertextCrc32c = crc32c.calculate(ciphertext);

async function decryptSymmetric() {
  const [decryptResponse] = await client.decrypt({
    name: keyName,
    ciphertext: ciphertext,
    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}`);
  return plaintext;
}

return decryptSymmetric();