;(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)); }; }());