使用 aws-sdk-v3 中的 KMS 客户端解密 cognito 代码

pko*_*lov 3 amazon-cognito amazon-kms aws-sdk-js aws-sdk-js-v3

我按照此说明在 Cognito 中实现自定义消息发送器https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-sms-sender.html

所有这些都适用于类似的代码(我在 AWS Lambda 上使用 Typescript):

import {buildClient, CommitmentPolicy, KmsKeyringNode} from '@aws-crypto/client-node';
import b64 from 'base64-js';

const {decrypt} = buildClient(CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT);
const keyring = new KmsKeyringNode({keyIds: ["my-key-arn"]});

...
const {plaintext} = await decrypt(keyring, b64.toByteArray(event.request.code));
console.log(plainttext.toString()) // prints plain text exactly as I need
Run Code Online (Sandbox Code Playgroud)

然而,这个库@aws-crypto/client-node让我的包变得非常巨大,几乎有 20MB!可能是因为它依赖于一些较旧的 AWS 库......

我曾经使用模块化库,这样的库@aws-sdk/xxx确实提供了更小的包。

我发现对于加密/解密我可以使用@aws-sdk/client-kms. 但这不起作用!

我正在尝试以下代码:

import {KMSClient, DecryptCommand} from "@aws-sdk/client-kms";
import b64 from 'base64-js';

const client = new KMSClient;
await client.send(new DecryptCommand({CiphertextBlob: b64.toByteArray(event.request.code), KeyId: 'my-key-arn'}))
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误:

InvalidCiphertextException: UnknownError
    at deserializeAws_json1_1InvalidCiphertextExceptionResponse (/projectdir/node_modules/@aws-sdk/client-kms/dist-cjs/protocols/Aws_json1_1.js:3157:23)
    at deserializeAws_json1_1DecryptCommandError (/projectdir/node_modules/@aws-sdk/client-kms/dist-cjs/protocols/Aws_json1_1.js:850:25)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /projectdir/node_modules/@aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
    at async /projectdir/node_modules/@aws-sdk/middleware-signing/dist-cjs/middleware.js:14:20
    at async StandardRetryStrategy.retry (/projectdir/node_modules/@aws-sdk/middleware-retry/dist-cjs/StandardRetryStrategy.js:51:46)
    at async /projectdir/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
    at async REPL7:1:33 {
  '$fault': 'client',
  '$metadata': {
    httpStatusCode: 400,
    requestId: '<uuid>',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  __type: 'InvalidCiphertextException'
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?这个KMSClient支持我的需要吗?

我也尝试过 AWS CLIaws kms decrypt --ciphertext-blob ...命令,给出了完全相同的响应。不过,如果我加密和解密任何随机消息(例如“hello world”),它就会像魅力一样发挥作用。

我做错了什么,Cognito 代码密文有什么特别之处,所以我必须以另一种方式解密它?

Ben*_*Ben 6

简短回答: Cognito 不使用 KMS 来加密文本,而是使用加密 SDK。所以你不能使用KMS来解密Cognito密文。

更长的答案:过去一天我试图使用 boto3 和 KMS 客户端让 Python 电子邮件发送器触发函数与 Cognito 一起工作,直到我发现另一篇文章(在某个地方?)解释 Cognito 不使用 KMS 加密数据,而是使用加密SDK。当然这两种加密机制是不兼容的。

对于 JavaScript 和 Node.js 应用程序,您似乎可以选择包含整个加密客户端:https://www.npmjs.com/package/@aws-crypto/decrypt-node

如果您所做的只是解密,上面的包将允许您使用 Encryption SDK 进行解密,并且它只有 159KB。