Removed last NodeJS 'crypto' dependency for browser use

This commit is contained in:
mhelander 2017-09-19 12:20:54 +03:00
parent dfe8e27047
commit c8f6b07e2e
2 changed files with 32 additions and 26 deletions

View File

@ -50,6 +50,7 @@
"@std/esm": "^0.8.3", "@std/esm": "^0.8.3",
"aws-sdk": ">=2.41.0", "aws-sdk": ">=2.41.0",
"formidable": ">=1.1.1", "formidable": ">=1.1.1",
"spark-md5": "^3.0.0",
"ws": "~>2.2.3" "ws": "~>2.2.3"
}, },
"devDependencies": { "devDependencies": {

57
sea.js
View File

@ -12,14 +12,16 @@
/* THIS IS AN EARLY ALPHA!!! */ /* THIS IS AN EARLY ALPHA!!! */
var crypto = require('crypto');
var Gun = (typeof window !== 'undefined' ? window : global).Gun || require('./gun'); var Gun = (typeof window !== 'undefined' ? window : global).Gun || require('./gun');
if(typeof Buffer === 'undefined'){ if(typeof Buffer === 'undefined'){
var Buffer = require('buffer').Buffer; var Buffer = require('buffer').Buffer;
} }
if(typeof SparkMD5 === 'undefined'){
var SparkMD5 = require('spark-md5');
}
var subtle, subtleossl, TextEncoder, TextDecoder, getRandomBytes; var subtle, subtleossl, TextEncoder, TextDecoder, getRandomBytes;
var sessionStorage, indexedDB; var sessionStorage, indexedDB;
@ -33,6 +35,7 @@
indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB
|| window.msIndexedDB || window.shimIndexedDB; || window.msIndexedDB || window.shimIndexedDB;
} else { } else {
var crypto = require('crypto');
var WebCrypto = require('node-webcrypto-ossl'); var WebCrypto = require('node-webcrypto-ossl');
var webcrypto = new WebCrypto({directory: 'key_storage'}); var webcrypto = new WebCrypto({directory: 'key_storage'});
subtleossl = webcrypto.subtle; subtleossl = webcrypto.subtle;
@ -47,7 +50,7 @@
// Encryption parameters - TODO: maybe to be changed via init? // Encryption parameters - TODO: maybe to be changed via init?
var pbkdf2 = { var pbkdf2 = {
hash: 'SHA-256', // Was 'SHA-1' hash: 'SHA-256',
iter: 50000, iter: 50000,
ks: 64 ks: 64
}; };
@ -459,15 +462,11 @@
} }
}); });
} }
// Takes data (defaults as Buffer) and returns 'md5' hash
function hashData(data,intype,outtype){
return crypto.createHash(outtype || 'md5').update(data, intype).digest();
}
// This internal func returns hashed data for signing // This internal func returns hashed data for signing
function nodehash(m){ function sha256hash(m){
var hashSubtle = subtleossl || subtle;
try{ m = m.slice ? m : JSON.stringify(m) }catch(e){} //eslint-disable-line no-empty try{ m = m.slice ? m : JSON.stringify(m) }catch(e){} //eslint-disable-line no-empty
return hashData(m, 'utf8', nHash); return hashSubtle.digest(pbkdf2.hash, new TextEncoder("utf-8").encode(m));
} }
// How does it work? // How does it work?
@ -855,13 +854,13 @@
// Does enc/dec key like OpenSSL - works with CryptoJS encryption/decryption // Does enc/dec key like OpenSSL - works with CryptoJS encryption/decryption
function makeKey(p,s){ function makeKey(p,s){
var ps = Buffer.concat([new Buffer(p, 'utf8'), s]); var ps = Buffer.concat([new Buffer(p, 'utf8'), s]);
// TODO: 'md5' is insecure, do we need OpenSSL compatibility anymore ? var h128 = new Buffer((new SparkMD5()).appendBinary(ps).end(true), 'binary');
var h128 = hashData(ps); return Buffer.concat([
return Buffer.concat([h128, hashData(Buffer.concat([h128, ps]))]); h128,
new Buffer((new SparkMD5()).appendBinary(Buffer.concat([h128, ps])).end(true), 'binary')
]);
} }
var nHash = pbkdf2.hash.replace('-', '').toLowerCase();
// These SEA functions support both callback AND Promises // These SEA functions support both callback AND Promises
var SEA = {}; var SEA = {};
// create a wrapper library around Web Crypto API. // create a wrapper library around Web Crypto API.
@ -884,7 +883,11 @@
}) || function(resolve, reject){ // For NodeJS crypto.pkdf2 rocks }) || function(resolve, reject){ // For NodeJS crypto.pkdf2 rocks
try{ try{
var hash = crypto.pbkdf2Sync( var hash = crypto.pbkdf2Sync(
pass, new Buffer(salt, 'utf8'), pbkdf2.iter, pbkdf2.ks, nHash pass,
new Buffer(salt, 'utf8'),
pbkdf2.iter,
pbkdf2.ks,
pbkdf2.hash.replace('-', '').toLowerCase()
); );
pass = getRandomBytes(pass.length); pass = getRandomBytes(pass.length);
resolve(hash && hash.toString('base64')); resolve(hash && hash.toString('base64'));
@ -963,15 +966,15 @@
if(cb){ doIt(cb, function(){cb()}) } else { return new Promise(doIt) } if(cb){ doIt(cb, function(){cb()}) } else { return new Promise(doIt) }
}; };
SEA.sign = function(m,p,cb){ SEA.sign = function(m,p,cb){
m = m.slice ? m : JSON.stringify(m);
var doIt = function(resolve, reject){ var doIt = function(resolve, reject){
var jwk = keystoecdsajwk(p.pub, p.priv); var jwk = keystoecdsajwk(p.pub, p.priv);
var mm = nodehash(m); sha256hash(m.slice ? m : JSON.stringify(m)).then(function(mm){
subtle.importKey('jwk', jwk, ecdsakeyprops, false, ['sign']).then(function(key){ subtle.importKey('jwk', jwk, ecdsakeyprops, false, ['sign']).then(function(key){
subtle.sign(ecdsasignprops, key, mm) subtle.sign(ecdsasignprops, key, mm)
.then(function(s){ resolve(new Buffer(s, 'binary').toString('base64')) }) .then(function(s){ resolve(new Buffer(s, 'binary').toString('base64')) })
.catch(function(e){ Gun.log(e); reject(e) }); .catch(function(e){ Gun.log(e); reject(e) });
}).catch(function(e){ Gun.log(e); reject(e) }); }).catch(function(e){ Gun.log(e); reject(e) });
});
}; };
if(cb){doIt(cb, function(){cb()})} else { return new Promise(doIt) } if(cb){doIt(cb, function(){cb()})} else { return new Promise(doIt) }
}; };
@ -979,9 +982,11 @@
var doIt = function(resolve, reject){ var doIt = function(resolve, reject){
subtle.importKey('jwk', keystoecdsajwk(p), ecdsakeyprops, false, ['verify']) subtle.importKey('jwk', keystoecdsajwk(p), ecdsakeyprops, false, ['verify'])
.then(function(key){ .then(function(key){
subtle.verify(ecdsasignprops, key, new Buffer(s, 'base64'), nodehash(m)) sha256hash(m).then(function(mm){
.then(function(v){ resolve(v) }) subtle.verify(ecdsasignprops, key, new Buffer(s, 'base64'), mm)
.catch(function(e){ Gun.log(e); reject(e) }); .then(function(v){ resolve(v) })
.catch(function(e){ Gun.log(e); reject(e) });
});
}).catch(function(e){ Gun.log(e); reject(e) }); }).catch(function(e){ Gun.log(e); reject(e) });
}; };
if(cb){doIt(cb, function(){cb()})} else { return new Promise(doIt) } if(cb){doIt(cb, function(){cb()})} else { return new Promise(doIt) }