Skip to content

Commit

Permalink
#21: Add auth tag support for gcm ccm ocb modes
Browse files Browse the repository at this point in the history
  • Loading branch information
generalpiston committed Jul 4, 2020
1 parent 900150f commit 20da54d
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12.16.0
12.18.0
144 changes: 102 additions & 42 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
"@types/node": "^9.6.0",
"chai": "^4.1.2",
"mocha": "^4.0.1",
"prettier": "^2.0.5",
"sqlite3": "^4.1.1",
"ts-node": "^3.3.0",
"tslint": "^5.8.0",
"typeorm": "^0.2.24",
"typeorm": "^0.2.25",
"typescript": "^3.3.3333"
},
"peerDependencies": {
Expand Down
55 changes: 40 additions & 15 deletions src/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,59 @@
import { createCipheriv, createDecipheriv, randomBytes } from 'crypto';
import { EncryptionOptions } from './options';

const DEFAULT_AUTH_TAG_LENGTH = 16;

function hasAuthTag(algorithm: string):boolean {
return algorithm.endsWith('-gcm') || algorithm.endsWith('-ccm') || algorithm.endsWith('-ocb')
}

/**
* Encrypt data.
*/
export function encryptData(data: Buffer, options: EncryptionOptions): Buffer {
let iv = options.iv
const { algorithm, authTagLength, ivLength, key } = options;
const iv = options.iv
? Buffer.from(options.iv, 'hex')
: randomBytes(options.ivLength);
let cipher = createCipheriv(
options.algorithm,
Buffer.from(options.key, 'hex'),
iv
: randomBytes(ivLength);
const cipherOptions = { authTagLength: authTagLength ?? DEFAULT_AUTH_TAG_LENGTH };
const cipher = (createCipheriv as any)(
algorithm,
Buffer.from(key, 'hex'),
iv,
cipherOptions
);
let start = cipher.update(data);
let final = cipher.final();
return Buffer.concat([iv, start, final]);
const start = cipher.update(data);
const final = cipher.final();

if (hasAuthTag(options.algorithm)) {
return Buffer.concat([iv, cipher.getAuthTag(), start, final]);
} else {
return Buffer.concat([iv, start, final]);
}
}

/**
* Decrypt data.
*/
export function decryptData(data: Buffer, options: EncryptionOptions): Buffer {
let iv = data.slice(0, options.ivLength);
let decipher = createDecipheriv(
options.algorithm,
Buffer.from(options.key, 'hex'),
const { algorithm, ivLength, key } = options;
const authTagLength = options.authTagLength ?? DEFAULT_AUTH_TAG_LENGTH;
const iv = data.slice(0, ivLength);
const decipher = createDecipheriv(
algorithm,
Buffer.from(key, 'hex'),
iv
);
let start = decipher.update(data.slice(options.ivLength));
let final = decipher.final();

let dataToUse = data.slice(options.ivLength);

if (hasAuthTag(options.algorithm)) {
decipher.setAuthTag(dataToUse.slice(0, authTagLength));
dataToUse = dataToUse.slice(authTagLength);
}

const start = decipher.update(dataToUse);
const final = decipher.final();

return Buffer.concat([start, final]);
}
Loading

0 comments on commit 20da54d

Please sign in to comment.