cs2-encryption
Version:
NodeJS Typescript implementation of cybersource v2 encryption
62 lines (61 loc) • 2.56 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.replace = exports.stringToArrayBuffer = exports.arrayBufferToString = exports.build = exports.wrapKey = exports.importKey = exports._encrypt = exports.generateKey = void 0;
const btoa_1 = __importDefault(require("btoa"));
exports.generateKey = (crypto) => crypto.subtle.generateKey({
name: 'AES-GCM',
length: 256
}, true, ['encrypt']);
exports._encrypt = async (crypto, payload, key, header, iv) => {
const algorithm = {
name: 'AES-GCM',
iv,
additionalData: exports.stringToArrayBuffer(exports.replace(JSON.stringify(header))),
tagLength: 128
};
const buffer = await crypto.subtle.encrypt(algorithm, key, exports.stringToArrayBuffer(JSON.stringify(payload)));
return [buffer, key];
};
exports.importKey = (crypto, jsonWebKey) => crypto.subtle.importKey('jwk', jsonWebKey, {
name: 'RSA-OAEP',
hash: {
name: 'SHA-1'
}
}, false, ['wrapKey']);
exports.wrapKey = async (crypto, key, jsonWebKey) => {
const wrappingKey = await exports.importKey(crypto, jsonWebKey);
// cast to `any` because web crypto types are all fucked up
const params = {
name: 'RSA-OAEP',
hash: {
name: 'SHA-1'
}
};
return crypto.subtle.wrapKey('raw', key, wrappingKey, params);
};
exports.build = async (crypto, buffer, key, iv, header, jsonWebKey) => {
// eslint-disable-next-line no-bitwise
const u = buffer.byteLength - ((128 + 7) >> 3);
const keyBuffer = await exports.wrapKey(crypto, key, jsonWebKey);
return [
exports.replace(JSON.stringify(header)),
exports.replace(exports.arrayBufferToString(keyBuffer)),
exports.replace(exports.arrayBufferToString(iv)),
exports.replace(exports.arrayBufferToString(buffer.slice(0, u))),
exports.replace(exports.arrayBufferToString(buffer.slice(u)))
].join('.');
};
exports.arrayBufferToString = (buf) => String.fromCharCode.apply(null, new Uint8Array(buf));
exports.stringToArrayBuffer = (str) => {
const buffer = new ArrayBuffer(str.length);
const array = new Uint8Array(buffer);
const { length } = str;
for (let r = 0; r < length; r += 1) {
array[r] = str.charCodeAt(r);
}
return buffer;
};
exports.replace = (str) => btoa_1.default(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');