Typescript Cipher.getAuthTag doesn't exists

Viewed 1748

I am trying to do encrypt/decrypt using this https://github.com/luke-park/SecureCompatibleEncryptionExamples but the Cipher definition doesn't have getAuthTag.

is there a @types should I install?

EDIT Just saw node/index.d.ts the getAuthTag and setAAD is is commented. I don't think it is right to remove the comment.

3 Answers

If you go to the declaration of Cipher in @types/node, you'll notice that it has subinterfaces that have getAuthTag:

    export interface Cipher extends NodeJS.ReadWriteStream {
        update(data: string | Buffer | NodeJS.TypedArray | DataView): Buffer;
        update(data: string, input_encoding: Utf8AsciiBinaryEncoding): Buffer;
        update(data: Buffer | NodeJS.TypedArray | DataView, output_encoding: HexBase64BinaryEncoding): string;
        update(data: Buffer | NodeJS.TypedArray | DataView, input_encoding: any, output_encoding: HexBase64BinaryEncoding): string;
        // second arg ignored
        update(data: string, input_encoding: Utf8AsciiBinaryEncoding, output_encoding: HexBase64BinaryEncoding): string;
        final(): Buffer;
        final(output_encoding: string): string;
        setAutoPadding(auto_padding?: boolean): this;
        // getAuthTag(): Buffer;
        // setAAD(buffer: Buffer): this; // docs only say buffer
    }
    export interface CipherCCM extends Cipher {
        setAAD(buffer: Buffer, options: { plaintextLength: number }): this;
        getAuthTag(): Buffer;
    }
    export interface CipherGCM extends Cipher {
        setAAD(buffer: Buffer, options?: { plaintextLength: number }): this;
        getAuthTag(): Buffer;
}

And createCipheriv has corresponding overloads: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/index.d.ts#L5914-L5916

export function createCipheriv(algorithm: CipherCCMTypes, key: string | Buffer | NodeJS.TypedArray | DataView, iv: string | Buffer | NodeJS.TypedArray | DataView, options: CipherCCMOptions): CipherCCM;
export function createCipheriv(algorithm: CipherGCMTypes, key: string | Buffer | NodeJS.TypedArray | DataView, iv: string | Buffer | NodeJS.TypedArray | DataView, options?: CipherGCMOptions): CipherGCM;
export function createCipheriv(algorithm: string, key: string | Buffer | NodeJS.TypedArray | DataView, iv: string | Buffer | NodeJS.TypedArray | DataView, options?: stream.TransformOptions): Cipher;

So if you pass an algorithm argument that is known at compile time to belong to CipherGCMTypes, then you should be able to call getAuthTag. If it's not working, please add your code to the question.

The reason for the issue you're having is because you're defining the algorithm as a string and it should be Cipher.CipherGCMTypes.

When you define the variable you declare the type. As Matt said, you have to pass it in as that type.

private ALGORITHM:crypto.CipherGCMTypes = 'aes-256-gcm';
let cipher:crypto.Cipher = crypto.createCipheriv(this.ALGORITHM, Buffer.from(this.encryptionKeyMessage, 'base64'), iv)

The accepted answer explains the "why" well. This answer is for those facing the issue and wondering what to try.

I faced this today. In my case, the algorithm was a variable that was resolved at runtime. The code below worked.

private algorithm: "aes-256-gcm" | "aes-128-gcm"; //see link below
//some code
const decipher = crypto.createDecipheriv(
  this.algorithm,
  Buffer.from(rawKey, "hex"),
  Buffer.from(iv)
);

TypeScript compiled this without issues.

References: How to require a specific string in TypeScript interface

Related