tink-crypto
Version:
A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.
89 lines • 10.1 kB
JavaScript
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { SecurityException } from '../exception/security_exception';
import * as Bytes from './bytes';
import * as Random from './random';
import * as Validators from './validators';
/**
* The minimum IV size.
*
*/
const MIN_IV_SIZE_IN_BYTES = 12;
/**
* AES block size.
*
*/
const AES_BLOCK_SIZE_IN_BYTES = 16;
/**
* Implementation of AES-CTR.
*
* @final
*/
export class AesCtr {
/**
* @param ivSize the size of the IV
*/
constructor(key, ivSize) {
this.key = key;
this.ivSize = ivSize;
}
/**
*/
encrypt(plaintext) {
return __awaiter(this, void 0, void 0, function* () {
Validators.requireUint8Array(plaintext);
const iv = Random.randBytes(this.ivSize);
const counter = new Uint8Array(AES_BLOCK_SIZE_IN_BYTES);
counter.set(iv);
const alg = { 'name': 'AES-CTR', 'counter': counter, 'length': 128 };
const ciphertext = yield self.crypto.subtle.encrypt(alg, this.key, plaintext);
return Bytes.concat(iv, new Uint8Array(ciphertext));
});
}
/**
*/
decrypt(ciphertext) {
return __awaiter(this, void 0, void 0, function* () {
Validators.requireUint8Array(ciphertext);
if (ciphertext.length < this.ivSize) {
throw new SecurityException('ciphertext too short');
}
const counter = new Uint8Array(AES_BLOCK_SIZE_IN_BYTES);
counter.set(ciphertext.subarray(0, this.ivSize));
const alg = { 'name': 'AES-CTR', 'counter': counter, 'length': 128 };
return new Uint8Array(yield self.crypto.subtle.decrypt(alg, this.key, new Uint8Array(ciphertext.subarray(this.ivSize))));
});
}
}
/**
* @param ivSize the size of the IV, must be larger than or equal to
* {@link MIN_IV_SIZE_IN_BYTES}
*/
export function fromRawKey(key, ivSize) {
return __awaiter(this, void 0, void 0, function* () {
if (!Number.isInteger(ivSize)) {
throw new SecurityException('invalid IV length, must be an integer');
}
if (ivSize < MIN_IV_SIZE_IN_BYTES || ivSize > AES_BLOCK_SIZE_IN_BYTES) {
throw new SecurityException('invalid IV length, must be at least ' + MIN_IV_SIZE_IN_BYTES +
' and at most ' + AES_BLOCK_SIZE_IN_BYTES);
}
Validators.requireUint8Array(key);
Validators.validateAesKeySize(key.length);
const cryptoKey = yield self.crypto.subtle.importKey('raw', key, { 'name': 'AES-CTR', 'length': key.length }, false, ['encrypt', 'decrypt']);
return new AesCtr(cryptoKey, ivSize);
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWVzX2N0ci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3N1YnRsZS9hZXNfY3RyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7Ozs7Ozs7Ozs7QUFFSCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQztBQUVsRSxPQUFPLEtBQUssS0FBSyxNQUFNLFNBQVMsQ0FBQztBQUVqQyxPQUFPLEtBQUssTUFBTSxNQUFNLFVBQVUsQ0FBQztBQUNuQyxPQUFPLEtBQUssVUFBVSxNQUFNLGNBQWMsQ0FBQztBQUUzQzs7O0dBR0c7QUFDSCxNQUFNLG9CQUFvQixHQUFXLEVBQUUsQ0FBQztBQUV4Qzs7O0dBR0c7QUFDSCxNQUFNLHVCQUF1QixHQUFXLEVBQUUsQ0FBQztBQUUzQzs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLE1BQU07SUFDakI7O09BRUc7SUFDSCxZQUNxQixHQUFjLEVBQW1CLE1BQWM7UUFBL0MsUUFBRyxHQUFILEdBQUcsQ0FBVztRQUFtQixXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQUcsQ0FBQztJQUV4RTtPQUNHO0lBQ0csT0FBTyxDQUFDLFNBQXFCOztZQUNqQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDeEMsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDekMsTUFBTSxPQUFPLEdBQUcsSUFBSSxVQUFVLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUN4RCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLE1BQU0sR0FBRyxHQUFHLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUMsQ0FBQztZQUNuRSxNQUFNLFVBQVUsR0FDWixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUMvRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztLQUFBO0lBRUQ7T0FDRztJQUNHLE9BQU8sQ0FBQyxVQUFzQjs7WUFDbEMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3pDLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNuQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0JBQXNCLENBQUMsQ0FBQzthQUNyRDtZQUNELE1BQU0sT0FBTyxHQUFHLElBQUksVUFBVSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDeEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNqRCxNQUFNLEdBQUcsR0FBRyxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFDLENBQUM7WUFDbkUsT0FBTyxJQUFJLFVBQVUsQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FDbEQsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztLQUFBO0NBQ0Y7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQWdCLFVBQVUsQ0FDNUIsR0FBZSxFQUFFLE1BQWM7O1FBQ2pDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzdCLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1NBQ3RFO1FBQ0QsSUFBSSxNQUFNLEdBQUcsb0JBQW9CLElBQUksTUFBTSxHQUFHLHVCQUF1QixFQUFFO1lBQ3JFLE1BQU0sSUFBSSxpQkFBaUIsQ0FDdkIsc0NBQXNDLEdBQUcsb0JBQW9CO2dCQUM3RCxlQUFlLEdBQUcsdUJBQXVCLENBQUMsQ0FBQztTQUNoRDtRQUNELFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFDLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUNoRCxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBQyxFQUFFLEtBQUssRUFDNUQsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUM1QixPQUFPLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbmltcG9ydCB7U2VjdXJpdHlFeGNlcHRpb259IGZyb20gJy4uL2V4Y2VwdGlvbi9zZWN1cml0eV9leGNlcHRpb24nO1xuXG5pbXBvcnQgKiBhcyBCeXRlcyBmcm9tICcuL2J5dGVzJztcbmltcG9ydCB7SW5kQ3BhQ2lwaGVyfSBmcm9tICcuL2luZF9jcGFfY2lwaGVyJztcbmltcG9ydCAqIGFzIFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5pbXBvcnQgKiBhcyBWYWxpZGF0b3JzIGZyb20gJy4vdmFsaWRhdG9ycyc7XG5cbi8qKlxuICogVGhlIG1pbmltdW0gSVYgc2l6ZS5cbiAqXG4gKi9cbmNvbnN0IE1JTl9JVl9TSVpFX0lOX0JZVEVTOiBudW1iZXIgPSAxMjtcblxuLyoqXG4gKiBBRVMgYmxvY2sgc2l6ZS5cbiAqXG4gKi9cbmNvbnN0IEFFU19CTE9DS19TSVpFX0lOX0JZVEVTOiBudW1iZXIgPSAxNjtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBBRVMtQ1RSLlxuICpcbiAqIEBmaW5hbFxuICovXG5leHBvcnQgY2xhc3MgQWVzQ3RyIGltcGxlbWVudHMgSW5kQ3BhQ2lwaGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSBpdlNpemUgdGhlIHNpemUgb2YgdGhlIElWXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkga2V5OiBDcnlwdG9LZXksIHByaXZhdGUgcmVhZG9ubHkgaXZTaXplOiBudW1iZXIpIHt9XG5cbiAgLyoqXG4gICAqL1xuICBhc3luYyBlbmNyeXB0KHBsYWludGV4dDogVWludDhBcnJheSk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIFZhbGlkYXRvcnMucmVxdWlyZVVpbnQ4QXJyYXkocGxhaW50ZXh0KTtcbiAgICBjb25zdCBpdiA9IFJhbmRvbS5yYW5kQnl0ZXModGhpcy5pdlNpemUpO1xuICAgIGNvbnN0IGNvdW50ZXIgPSBuZXcgVWludDhBcnJheShBRVNfQkxPQ0tfU0laRV9JTl9CWVRFUyk7XG4gICAgY291bnRlci5zZXQoaXYpO1xuICAgIGNvbnN0IGFsZyA9IHsnbmFtZSc6ICdBRVMtQ1RSJywgJ2NvdW50ZXInOiBjb3VudGVyLCAnbGVuZ3RoJzogMTI4fTtcbiAgICBjb25zdCBjaXBoZXJ0ZXh0ID1cbiAgICAgICAgYXdhaXQgc2VsZi5jcnlwdG8uc3VidGxlLmVuY3J5cHQoYWxnLCB0aGlzLmtleSwgcGxhaW50ZXh0KTtcbiAgICByZXR1cm4gQnl0ZXMuY29uY2F0KGl2LCBuZXcgVWludDhBcnJheShjaXBoZXJ0ZXh0KSk7XG4gIH1cblxuICAvKipcbiAgICovXG4gIGFzeW5jIGRlY3J5cHQoY2lwaGVydGV4dDogVWludDhBcnJheSk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIFZhbGlkYXRvcnMucmVxdWlyZVVpbnQ4QXJyYXkoY2lwaGVydGV4dCk7XG4gICAgaWYgKGNpcGhlcnRleHQubGVuZ3RoIDwgdGhpcy5pdlNpemUpIHtcbiAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbignY2lwaGVydGV4dCB0b28gc2hvcnQnKTtcbiAgICB9XG4gICAgY29uc3QgY291bnRlciA9IG5ldyBVaW50OEFycmF5KEFFU19CTE9DS19TSVpFX0lOX0JZVEVTKTtcbiAgICBjb3VudGVyLnNldChjaXBoZXJ0ZXh0LnN1YmFycmF5KDAsIHRoaXMuaXZTaXplKSk7XG4gICAgY29uc3QgYWxnID0geyduYW1lJzogJ0FFUy1DVFInLCAnY291bnRlcic6IGNvdW50ZXIsICdsZW5ndGgnOiAxMjh9O1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCBzZWxmLmNyeXB0by5zdWJ0bGUuZGVjcnlwdChcbiAgICAgICAgYWxnLCB0aGlzLmtleSwgbmV3IFVpbnQ4QXJyYXkoY2lwaGVydGV4dC5zdWJhcnJheSh0aGlzLml2U2l6ZSkpKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0gaXZTaXplIHRoZSBzaXplIG9mIHRoZSBJViwgbXVzdCBiZSBsYXJnZXIgdGhhbiBvciBlcXVhbCB0b1xuICogICAgIHtAbGluayBNSU5fSVZfU0laRV9JTl9CWVRFU31cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZyb21SYXdLZXkoXG4gICAga2V5OiBVaW50OEFycmF5LCBpdlNpemU6IG51bWJlcik6IFByb21pc2U8SW5kQ3BhQ2lwaGVyPiB7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihpdlNpemUpKSB7XG4gICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCdpbnZhbGlkIElWIGxlbmd0aCwgbXVzdCBiZSBhbiBpbnRlZ2VyJyk7XG4gIH1cbiAgaWYgKGl2U2l6ZSA8IE1JTl9JVl9TSVpFX0lOX0JZVEVTIHx8IGl2U2l6ZSA+IEFFU19CTE9DS19TSVpFX0lOX0JZVEVTKSB7XG4gICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAnaW52YWxpZCBJViBsZW5ndGgsIG11c3QgYmUgYXQgbGVhc3QgJyArIE1JTl9JVl9TSVpFX0lOX0JZVEVTICtcbiAgICAgICAgJyBhbmQgYXQgbW9zdCAnICsgQUVTX0JMT0NLX1NJWkVfSU5fQllURVMpO1xuICB9XG4gIFZhbGlkYXRvcnMucmVxdWlyZVVpbnQ4QXJyYXkoa2V5KTtcbiAgVmFsaWRhdG9ycy52YWxpZGF0ZUFlc0tleVNpemUoa2V5Lmxlbmd0aCk7XG4gIGNvbnN0IGNyeXB0b0tleSA9IGF3YWl0IHNlbGYuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoXG4gICAgICAncmF3Jywga2V5LCB7J25hbWUnOiAnQUVTLUNUUicsICdsZW5ndGgnOiBrZXkubGVuZ3RofSwgZmFsc2UsXG4gICAgICBbJ2VuY3J5cHQnLCAnZGVjcnlwdCddKTtcbiAgcmV0dXJuIG5ldyBBZXNDdHIoY3J5cHRvS2V5LCBpdlNpemUpO1xufVxuIl19