镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

the argument to define auth tag length in crypto.createDecipheriv cannot work #40272

Description

@duomaomao27
  • Node.js Version: 14.8.0
  • OS: MacOS 10.15.7
  • Scope (install, code, runtime, meta, other?): Typescript
  • Module (and version) (if relevant):

For 'aes-256-gcm', I've tried to use:

let decipher = crypto.createDecipheriv('aes-256-gcm', serverKeyArr, iv, {authTagLength: 12});

to define auth tag to 12 bytes, however, when I execute decipher.final(), inside that function, the tag it calculated is still 16 bytes, then when it do xor test for the tag function calculated and the auth Tag I've received (which already cut off by server side from 16 bytes to 12 bytes), it will results in error because the length is different.

I wonder why the argument {authTagLength: 12} do not work?

Besides, is there any way I can use shorter auth tag length to pass decipher.final() function, because in my program, I only can get the first 12 bytes auth tag.

Thanks

Activity

  1. mscdex commented on Sep 30, 2021

    @mscdex
    Contributor

    It's always returned 16 bytes for the actual tag data. You will need to manually slice off the first authTagLength bytes of the full tag to get the value you want.

    Arguably node should only be returning the appropriate slice of the full tag if the authTagLength is less than 16.

  2. transferred this issue fromnodejs/helpon Sep 30, 2021
  3. added
    cryptoIssues and PRs related to the crypto subsystem.
    on Sep 30, 2021
  4. tniessen commented on Nov 3, 2021

    @tniessen
    Member

    Besides, is there any way I can use shorter auth tag length to pass decipher.final() function, because in my program, I only can get the first 12 bytes auth tag.

    You can pass shorter tags to setAuthTag() as long as the length is valid according to SP 800-38D.

    Arguably node should only be returning the appropriate slice of the full tag if the authTagLength is less than 16.

    This should be working already ever since #20235:

    const cipher = crypto.createCipheriv('aes-128-gcm', Buffer.alloc(16), Buffer.alloc(16), {
      authTagLength: 4
    });
    cipher.update('foo');
    cipher.final();
    console.log(cipher.getAuthTag().byteLength); // prints 4
  5. tniessen commented on Nov 3, 2021

    @tniessen
    Member

    Testing in Node.js v14.17.5:

    const serverKeyArr = crypto.randomBytes(32);
    const iv = crypto.randomBytes(16);

    Producing a 12-byte authentication tag:

    const cipher = crypto.createCipheriv('aes-256-gcm', serverKeyArr, iv, {authTagLength: 12});
    const ciphertext = cipher.update('foo');
    cipher.final(); // GCM mode is a counter mode, so no output here
    const authTag = cipher.getAuthTag();
    console.log(authTag.length); // prints 12

    Now decrypting and verifying the tag, taking this line from your example:

    let decipher = crypto.createDecipheriv('aes-256-gcm', serverKeyArr, iv, {authTagLength: 12});

    This works and prints the correct plaintext:

    const plaintext = decipher.update(ciphertext);
    decipher.setAuthTag(authTag);
    decipher.final();
    console.log(plaintext.toString()); // prints 'foo'
  6. tniessen commented on Nov 11, 2021

    @tniessen
    Member

    I am closing this as answered. Feel free to reopen if the problem persists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cryptoIssues and PRs related to the crypto subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions