Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to decode Ciphertext: required version of backing key is invalid #68

Closed
beerfranz opened this issue Feb 15, 2024 · 2 comments
Closed

Comments

@beerfranz
Copy link

Hello !

I try to use local-kms with cognito-local, and I have an issue on decryption. cognito-local encrypt a code, send it to a lambda that decrypt the code to send it by email.

Local-kms logs:

kms-1  | INFO[2024-02-15 15:59:28.661] Data key generated with plaintext: arn:aws:kms:us-west-2:999999999:key/bc436485-5092-42b8-92a3-0aa8b93536c 
kms-1  | INFO[2024-02-15 15:59:28.663] Encryption called: arn:aws:kms:us-west-2:999999999:key/bc436485-5092-42b8-92a3-0aa8b93536c 
kms-1  | WARN[2024-02-15 15:59:28.864] Unable to decode Ciphertext: required version of backing key is invalid

Seed.yaml (same as the README.md):

Keys:
  Symmetric:
    Aes:
      - Metadata:
          KeyId: bc436485-5092-42b8-92a3-0aa8b93536c
        BackingKeys:
          - 5cdaead27fe7da2de47945d73cd6d79e36494e73802f3cd3869f1d2cb0b5d7a9
Aliases:
  - AliasName: alias/testing
    TargetKeyId: bc436485-5092-42b8-92a3-0aa8b93536c

My JS code to ask for decryption:

  const { KMSClient, DecryptCommand } = require("@aws-sdk/client-kms");
  const client = new KMSClient({ endpoint: 'http://kms:8080' });

  const encryptedString = event.request.code;
  const blob = Buffer.from(encryptedString, 'base64');
  const input = {
    CiphertextBlob: blob,
    KeyId: "arn:aws:kms:us-west-2:999999999:key/bc436485-5092-42b8-92a3-0aa8b93536c",
  };

  const command = new DecryptCommand(input);
  const response = await client.send(command);

This is the value of encryptedString:

AgV48tKFNiOC7/dmZoXQiT9U3VLm2x4dALXTRYyc+YRL/cgAXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREFpQ2pXcGxWcXIxMmxWcTB2Y0tKWXBBMVBmMGZiR2Y1SEhFUzgwMlo2di9VSGk2NGFnSGQ5dnh1VktmZGN3cXhrZz09AAIAB2F3cy1rbXMAR2Fybjphd3M6a21zOnVzLXdlc3QtMjo5OTk5OTk5OTk6a2V5L2JjNDM2NDg1LTUwOTItNDJiOC05MmEzLTBhYThiOTM1MzZjAIhHYXJuOmF3czprbXM6dXMtd2VzdC0yOjk5OTk5OTk5OTprZXkvYmM0MzY0ODUtNTA5Mi00MmI4LTkyYTMtMGFhOGI5MzUzNmMAAAAAVUO1tqKgbLqMBsdHg05VgY8yk2gDJxxKcvbII6unarm4MNHISFjjCpY41K8ClwuTuRn93Z48Id0t+2ZmAAdhd3Mta21zAEdhcm46YXdzOmttczp1cy13ZXN0LTI6OTk5OTk5OTk5OmtleS9iYzQzNjQ4NS01MDkyLTQyYjgtOTJhMy0wYWE4YjkzNTM2YwCIR2Fybjphd3M6a21zOnVzLXdlc3QtMjo5OTk5OTk5OTk6a2V5L2JjNDM2NDg1LTUwOTItNDJiOC05MmEzLTBhYThiOTM1MzZjAAAAAOg9H9NuUsisTJYhBqSiDMsqKQA4fZOLr+MJMwapxhkAf/yT+zBxOUoY/SsluCCIptu59T51W+4/N8VRqAIAABAAX1hx7OYRDIFU4NV8Pi4PtrxQS/D7dPdoKpZWEsmCbJDu+vMTC7ZCVpIeSdCNn5kH/////wAAAAEAAAAAAAAAAAAAAAEAAAAGStSchSe9W3+sdXJ9V1CU1quJ86wgSABoMGYCMQD1q2QYTQ7DUzqxJXoNpvl+FYSKy4W5Aw2YANzNy7Lc9ZLfeVMz1Ltv6GCITSVSCiQCMQCUFJK2OXcV1WZfQUq7GB4SGSbt4seIhZlLxacguQkcQ4BcLOM08KAPJZkNZ/tiAy4=

And the blob that is send to local-kms:

<Buffer 02 05 78 f2 d2 85 36 23 82 ef f7 66 66 85 d0 89 3f 54 dd 52 e6 db 1e 1d 00 b5 d3 45 8c 9c f9 84 4b fd c8 00 5f 00 01 00 15 61 77 73 2d 63 72 79 70 74 ... 729 more bytes>

Lambda logs:

serverless-1  | × InvalidCiphertextException: UnknownError
serverless-1  |       at de_InvalidCiphertextExceptionRes (/usr/src/app/node_modules/@aws-sdk/client-kms/dist-cjs/index.js:2634:21)
serverless-1  |       at de_CommandError (/usr/src/app/node_modules/@aws-sdk/client-kms/dist-cjs/index.js:2417:19)
serverless-1  |       at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
serverless-1  |       at async /usr/src/app/node_modules/@smithy/middleware-serde/dist-cjs/index.js:35:20
serverless-1  |       at async /usr/src/app/node_modules/@smithy/core/dist-cjs/index.js:165:18
serverless-1  |       at async /usr/src/app/node_modules/@smithy/middleware-retry/dist-cjs/index.js:320:38
serverless-1  |       at async /usr/src/app/node_modules/@aws-sdk/middleware-logger/dist-cjs/index.js:33:22
serverless-1  |       at async module.exports.handler (/usr/src/app/email.js:163:20)
serverless-1  |       at async MessagePort.<anonymous> (file:///usr/local/lib/node_modules/serverless-offline/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js:24:14)

I've tried to retry from start with a backingKey generated with openssl rand -hex 32, but I still have this error message.

Can I have some inputs to help me to solve this please ?

@beerfranz
Copy link
Author

I can reproduce the issue with a simple curl:

curl -X POST http://localhost:8080/ -H 'X-Amz-Target:TrentService.Decrypt' -d '{ "CiphertextBlob": "AgV48tKFNiOC7/dmZoXQiT9U3VLm2x4dALXTRYyc+YRL/cgAXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREFpQ2pXcGxWcXIxMmxWcTB2Y0tKWXBBMVBmMGZiR2Y1SEhFUzgwMlo2di9VSGk2NGFnSGQ5dnh1VktmZGN3cXhrZz09AAIAB2F3cy1rbXMAR2Fybjphd3M6a21zOnVzLXdlc3QtMjo5OTk5OTk5OTk6a2V5L2JjNDM2NDg1LTUwOTItNDJiOC05MmEzLTBhYThiOTM1MzZjAIhHYXJuOmF3czprbXM6dXMtd2VzdC0yOjk5OTk5OTk5OTprZXkvYmM0MzY0ODUtNTA5Mi00MmI4LTkyYTMtMGFhOGI5MzUzNmMAAAAAVUO1tqKgbLqMBsdHg05VgY8yk2gDJxxKcvbII6unarm4MNHISFjjCpY41K8ClwuTuRn93Z48Id0t+2ZmAAdhd3Mta21zAEdhcm46YXdzOmttczp1cy13ZXN0LTI6OTk5OTk5OTk5OmtleS9iYzQzNjQ4NS01MDkyLTQyYjgtOTJhMy0wYWE4YjkzNTM2YwCIR2Fybjphd3M6a21zOnVzLXdlc3QtMjo5OTk5OTk5OTk6a2V5L2JjNDM2NDg1LTUwOTItNDJiOC05MmEzLTBhYThiOTM1MzZjAAAAAOg9H9NuUsisTJYhBqSiDMsqKQA4fZOLr+MJMwapxhkAf/yT+zBxOUoY/SsluCCIptu59T51W+4/N8VRqAIAABAAX1hx7OYRDIFU4NV8Pi4PtrxQS/D7dPdoKpZWEsmCbJDu+vMTC7ZCVpIeSdCNn5kH/////wAAAAEAAAAAAAAAAAAAAAEAAAAGStSchSe9W3+sdXJ9V1CU1quJ86wgSABoMGYCMQD1q2QYTQ7DUzqxJXoNpvl+FYSKy4W5Aw2YANzNy7Lc9ZLfeVMz1Ltv6GCITSVSCiQCMQCUFJK2OXcV1WZfQUq7GB4SGSbt4seIhZlLxacguQkcQ4BcLOM08KAPJZkNZ/tiAy4=", "KeyId": "arn:aws:kms:us-west-2:999999999:key/bc436485-5092-42b8-92a3-0aa8b93536c" }' -H 'Content-type: application/json'

{"__type":"InvalidCiphertextException"}

local-kms log: Unable to decode Ciphertext: required version of backing key is invalid

If I follow the httpie example from the readme, only the CiphertextBlob is required in the decrypt request, and:

curl -X POST http://localhost:8080/ -H 'X-Amz-Target:TrentService.Decrypt' -d '{ "CiphertextBlob": "AgV48tKFNiOC7/dmZoXQiT9U3VLm2x4dALXTRYyc+YRL/cgAXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREFpQ2pXcGxWcXIxMmxWcTB2Y0tKWXBBMVBmMGZiR2Y1SEhFUzgwMlo2di9VSGk2NGFnSGQ5dnh1VktmZGN3cXhrZz09AAIAB2F3cy1rbXMAR2Fybjphd3M6a21zOnVzLXdlc3QtMjo5OTk5OTk5OTk6a2V5L2JjNDM2NDg1LTUwOTItNDJiOC05MmEzLTBhYThiOTM1MzZjAIhHYXJuOmF3czprbXM6dXMtd2VzdC0yOjk5OTk5OTk5OTprZXkvYmM0MzY0ODUtNTA5Mi00MmI4LTkyYTMtMGFhOGI5MzUzNmMAAAAAVUO1tqKgbLqMBsdHg05VgY8yk2gDJxxKcvbII6unarm4MNHISFjjCpY41K8ClwuTuRn93Z48Id0t+2ZmAAdhd3Mta21zAEdhcm46YXdzOmttczp1cy13ZXN0LTI6OTk5OTk5OTk5OmtleS9iYzQzNjQ4NS01MDkyLTQyYjgtOTJhMy0wYWE4YjkzNTM2YwCIR2Fybjphd3M6a21zOnVzLXdlc3QtMjo5OTk5OTk5OTk6a2V5L2JjNDM2NDg1LTUwOTItNDJiOC05MmEzLTBhYThiOTM1MzZjAAAAAOg9H9NuUsisTJYhBqSiDMsqKQA4fZOLr+MJMwapxhkAf/yT+zBxOUoY/SsluCCIptu59T51W+4/N8VRqAIAABAAX1hx7OYRDIFU4NV8Pi4PtrxQS/D7dPdoKpZWEsmCbJDu+vMTC7ZCVpIeSdCNn5kH/////wAAAAEAAAAAAAAAAAAAAAEAAAAGStSchSe9W3+sdXJ9V1CU1quJ86wgSABoMGYCMQD1q2QYTQ7DUzqxJXoNpvl+FYSKy4W5Aw2YANzNy7Lc9ZLfeVMz1Ltv6GCITSVSCiQCMQCUFJK2OXcV1WZfQUq7GB4SGSbt4seIhZlLxacguQkcQ4BcLOM08KAPJZkNZ/tiAy4=" }' -H 'Content-type: application/json'
{"Message":"The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access.","__type":"AccessDeniedException"}

local-kms log: Key 'arn:aws:kms:us-west-2:999999999:key/x' does not exist

It means that the CiphertextBlob is not correct ?

@beerfranz
Copy link
Author

Ok, the issue was in my lambda code.

Just need to follow the code example here: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-email-sender.html

A working code is:

const b64 = require('base64-js');
const encryptionSdk = require('@aws-crypto/client-node');

const { encrypt, decrypt } = encryptionSdk.buildClient(encryptionSdk.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT);

const generatorKeyId = process.env.KEY_ALIAS;
const keyIds = [ process.env.KEY_ARN ];
const keyring = new encryptionSdk.KmsKeyringNode({ generatorKeyId, keyIds });

const { createTransport } = require('nodemailer');

module.exports.handler = async (event, context, callback) => {

  const from = 'local@local';
  const to = event.request.userAttributes.email;

  //Decrypt the secret code using encryption SDK.
  let plainTextCode;
  if(event.request.code){
    const { plaintext, messageHeader } = await decrypt(keyring, b64.toByteArray(event.request.code));
    plainTextCode = plaintext
  }

  //PlainTextCode now contains the decrypted secret.
  if(event.triggerSource == 'CustomEmailSender_SignUp'){
    //Send an email message to your user via a custom provider.
    //Include the temporary password in the message.
    const email = await emailSender(from, to, 'Code', plainTextCode);
  }
  else if(event.triggerSource == 'CustomEmailSender_ResendCode'){
  }
  else if(event.triggerSource == 'CustomEmailSender_ForgotPassword'){
  }
  else if(event.triggerSource == 'CustomEmailSender_UpdateUserAttribute'){
  }
  else if(event.triggerSource == 'CustomEmailSender_VerifyUserAttribute'){
  }
  else if(event.triggerSource == 'CustomEmailSender_AdminCreateUser'){
  }
  else if(event.triggerSource == 'CustomEmailSender_AccountTakeOverNotification'){
  }
  return;
};

Sorry for the disruption! ^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant