oauth3.js/browserify/crypto-index.js

75 lines
2.6 KiB
JavaScript
Raw Normal View History

;(function () {
'use strict';
var createHash = require('create-hash');
var pbkdf2 = require('pbkdf2');
var aes = require('browserify-aes');
var ec = require('elliptic').ec('p256');
function sha256(buf) {
return createHash('sha256').update(buf).digest();
}
function encrypt(data, password, salt, iv) {
// Derived AES key is 128 bit, and the function takes a size in bytes.
var aesKey = pbkdf2.pbkdf2Sync(password, Buffer(salt), 8192, 16, 'sha256');
var cipher = aes.createCipheriv('aes-128-gcm', aesKey, Buffer(iv));
return Buffer.concat([cipher.update(Buffer(data)), cipher.final(), cipher.getAuthTag()]);
}
function decrypt(data, password, salt, iv) {
var aesKey = pbkdf2.pbkdf2Sync(password, Buffer(salt), 8192, 16, 'sha256');
var decipher = aes.createDecipheriv('aes-128-gcm', aesKey, Buffer(iv));
decipher.setAuthTag(Buffer(data.slice(-16)));
return Buffer.concat([decipher.update(Buffer(data.slice(0, -16))), decipher.final()]);
}
function convertBN(bn) {
if (bn.red) {
bn = bn.fromRed();
}
var b64 = bn.toArrayLike(Buffer).toString('base64');
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=*$/, '');
}
function genEcdsaKeyPair() {
var key = ec.genKeyPair();
var pubJwk = {
key_ops: ['verify']
, kty: 'EC'
, crv: 'P-256'
, x: convertBN(key.getPublic().x)
, y: convertBN(key.getPublic().y)
};
var privJwk = JSON.parse(JSON.stringify(pubJwk));
privJwk.key_ops = ['sign'];
privJwk.d = convertBN(key.getPrivate());
return {privateKey: privJwk, publicKey: pubJwk};
}
function sign(jwk, msg) {
var key = ec.keyFromPrivate(Buffer(jwk.d, 'base64'));
var sig = key.sign(sha256(msg));
return Buffer.concat([Buffer(sig.r, 'hex'), Buffer(sig.s, 'hex')]);
}
function verify(jwk, msg, signature) {
var key = ec.keyFromPublic({x: Buffer(jwk.x, 'base64'), y: Buffer(jwk.y, 'base64')});
var sig = {
r: Buffer(signature.slice(0, signature.length/2))
, s: Buffer(signature.slice(signature.length/2))
};
return key.verify(sha256(msg), sig);
}
exports.sha256 = function () { return Promise.resolve(sha256.apply(this, arguments)); };
exports.encrypt = function () { return Promise.resolve(encrypt.apply(this, arguments)); };
exports.decrypt = function () { return Promise.resolve(decrypt.apply(this, arguments)); };
exports.sign = function () { return Promise.resolve(sign.apply(this, arguments)); };
exports.verify = function () { return Promise.resolve(verify.apply(this, arguments)); };
exports.genEcdsaKeyPair = function () { return Promise.resolve(genEcdsaKeyPair.apply(this, arguments)); };
}());