hoodie-plugin-store-crypto
Advanced tools
Comparing version 4.1.1 to 4.1.2
'use strict' | ||
var Buffer = require('buffer/').Buffer | ||
var pbkdf2 = require('pbkdf2') | ||
var Promise = require('lie') | ||
var randomBytes = require('randombytes') | ||
var getCrypto = require('./utils/get-web-crypto') | ||
module.exports = function createKey (password, saltArg) { | ||
var subtle = getCrypto().subtle | ||
var passwordBuffer = toBuffer(password, 'utf-8', 'password') | ||
var digest = 'SHA-256' | ||
var digest = 'sha256' | ||
var iterations = 100000 | ||
var keyLength = 256 / 8 | ||
var salt = saltArg != null && typeof saltArg === 'string' && saltArg.length === 32 | ||
? saltArg | ||
: randomBytes(16).toString('hex') | ||
var saltyBuffy = Buffer.from(salt, 'hex') | ||
return subtle.importKey('raw', passwordBuffer, { name: 'PBKDF2' }, false, ['deriveBits']) | ||
return new Promise(function (resolve, reject) { | ||
var saltyBuffy = Buffer.from(salt, 'hex') | ||
.then(function (key) { | ||
return subtle.deriveBits( | ||
{ | ||
name: 'PBKDF2', | ||
salt: saltyBuffy, | ||
iterations: iterations, | ||
hash: { | ||
name: digest | ||
} | ||
}, | ||
key, | ||
keyLength << 3 | ||
) | ||
}) | ||
.then(function (res) { | ||
return { | ||
key: Buffer.from(res), | ||
salt: salt | ||
pbkdf2.pbkdf2(password, saltyBuffy, iterations, 256 / 8, digest, function (err, key) { | ||
if (err) { | ||
reject(err) | ||
} else { | ||
resolve({ | ||
key: key, | ||
salt: salt | ||
}) | ||
} | ||
}) | ||
}) | ||
} | ||
function toBuffer (thing, encoding, name) { | ||
if (Buffer.isBuffer(thing)) { | ||
return thing | ||
} else if (typeof thing === 'string') { | ||
return Buffer.from(thing, encoding) | ||
} else if (ArrayBuffer.isView(thing)) { | ||
return Buffer.from(thing.buffer) | ||
} else { | ||
throw new TypeError(name + ' must be a string, a Buffer, a typed array or a DataView') | ||
} | ||
} |
@@ -5,4 +5,5 @@ 'use strict' | ||
var aes = require('browserify-aes') | ||
var Buffer = require('buffer/').Buffer | ||
var getCrypto = require('../utils/get-web-crypto') | ||
var subtle = require('../utils/get-web-crypto') | ||
@@ -22,30 +23,91 @@ /** | ||
} | ||
var subtle = getCrypto().subtle | ||
return subtle.importKey('raw', key, { name: 'AES-GCM' }, true, ['decrypt']) | ||
return checkBrowser() | ||
.then(function (cryptoKey) { | ||
var options = { | ||
name: 'AES-GCM', | ||
iv: iv | ||
} | ||
// Original implementation from: | ||
// https://github.com/calvinmetcalf/native-crypto/blob/master/browser/decrypt.js | ||
.then(function (supportsBrowserCrypto) { | ||
// for when the browser supports crypto.subtle | ||
if (supportsBrowserCrypto) { | ||
return subtle.importKey('raw', key, { name: 'AES-GCM' }, true, ['decrypt']) | ||
if (aad != null) { | ||
options.additionalData = aad | ||
.then(function (cryptoKey) { | ||
var options = { | ||
name: 'AES-GCM', | ||
iv: iv | ||
} | ||
if (aad != null) { | ||
options.additionalData = aad | ||
} | ||
var encryptedData = Buffer.concat([data, tag]) | ||
return subtle.decrypt(options, cryptoKey, encryptedData) | ||
}) | ||
.then(function (result) { | ||
return Buffer.from(result).toString() | ||
}) | ||
} else { | ||
// fall back to browserify-aes | ||
var cipher = aes.createDecipheriv('aes-256-gcm', key, iv) | ||
if (aad != null) { | ||
cipher.setAAD(aad) | ||
} | ||
cipher.setAuthTag(tag) | ||
var output = cipher.update(data) | ||
cipher.final() | ||
return output.toString() | ||
} | ||
}) | ||
} | ||
var encryptedData = Buffer.concat([data, tag]) | ||
return subtle.decrypt(options, cryptoKey, encryptedData) | ||
var canUseBrowserCrypto = null | ||
/** | ||
* This checks if the browser supports crypto.subtle and the used encryption algorithm. | ||
*/ | ||
function checkBrowser () { | ||
if (global.process && !global.process.browser) { | ||
return Promise.resolve(false) | ||
} | ||
if (!subtle || !subtle.importKey || !subtle.encrypt) { | ||
return Promise.resolve(false) | ||
} | ||
if (canUseBrowserCrypto != null) { | ||
return Promise.resolve(canUseBrowserCrypto) | ||
} | ||
var zeroBuffy = Buffer.alloc(16, 0) | ||
return subtle.importKey('raw', zeroBuffy, { name: 'AES-GCM' }, true, ['decrypt']) | ||
.then(function (key) { | ||
return subtle.decrypt( | ||
{ | ||
name: 'AES-GCM', | ||
iv: zeroBuffy.slice(0, 12), | ||
additionalData: zeroBuffy.slice(0, 8) | ||
}, | ||
key, | ||
Buffer.from( | ||
'A4jazmC2o5LzKMK5cbL+ePeVqqtJS1kj9/2J/5SLweAgAhEhTnOU2iCJtqzQk6vgyU2iGRG' + | ||
'OKX17fry8ycOI8p7MWbwdPpusE+GvoYsO2TE=', | ||
'base64' | ||
) | ||
) | ||
}) | ||
.then(function (result) { | ||
return Buffer.from(result).toString() | ||
canUseBrowserCrypto = Buffer.from(result).toString('base64') === | ||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==' | ||
return canUseBrowserCrypto | ||
}) | ||
.catch(function (err) { | ||
if (err.type === 'error' && err.data instanceof Error) { | ||
throw err.data | ||
} | ||
throw err | ||
.catch(function () { | ||
canUseBrowserCrypto = false | ||
return canUseBrowserCrypto | ||
}) | ||
} |
@@ -5,5 +5,6 @@ 'use strict' | ||
var aes = require('browserify-aes') | ||
var Buffer = require('buffer/').Buffer | ||
var Promise = require('lie') | ||
var getCrypto = require('../utils/get-web-crypto') | ||
var subtle = require('../utils/get-web-crypto') | ||
@@ -22,34 +23,92 @@ /** | ||
} | ||
var subtle = getCrypto().subtle | ||
return subtle.importKey('raw', key, { name: 'AES-GCM' }, true, ['encrypt']) | ||
return checkBrowser() | ||
.then(function (key) { | ||
var options = { | ||
name: 'AES-GCM', | ||
iv: iv | ||
} | ||
// Original implementation from: | ||
// https://github.com/calvinmetcalf/native-crypto/blob/master/browser/encrypt.js | ||
.then(function (supportsBrowserCrypto) { | ||
// for when the browser supports crypto.subtle | ||
if (supportsBrowserCrypto) { | ||
return subtle.importKey('raw', key, { name: 'AES-GCM' }, true, ['encrypt']) | ||
if (aad != null) { | ||
options.additionalData = aad | ||
.then(function (key) { | ||
var options = { | ||
name: 'AES-GCM', | ||
iv: iv | ||
} | ||
if (aad != null) { | ||
options.additionalData = aad | ||
} | ||
return subtle.encrypt(options, key, data) | ||
}) | ||
.then(function (response) { | ||
var buffy = Buffer.from(response) | ||
return { | ||
tag: buffy.slice(-16).toString('hex'), | ||
data: buffy.slice(0, -16).toString('hex') | ||
} | ||
}) | ||
} else { | ||
// fall back to browserify-aes | ||
var cipher = aes.createCipheriv('aes-256-gcm', key, iv) | ||
if (aad != null) { | ||
cipher.setAAD(aad) | ||
} | ||
var output = cipher.update(data) | ||
cipher.final() | ||
var tag = cipher.getAuthTag() | ||
return { | ||
tag: tag.toString('hex'), | ||
data: output.toString('hex') | ||
} | ||
} | ||
}) | ||
} | ||
return subtle.encrypt(options, key, data) | ||
var canUseBrowserCrypto = null | ||
/** | ||
* This checks if the browser supports crypto.subtle and the used encryption algorithm. | ||
*/ | ||
function checkBrowser () { | ||
if (global.process && !global.process.browser) { | ||
return Promise.resolve(false) | ||
} | ||
if (!subtle || !subtle.importKey || !subtle.encrypt) { | ||
return Promise.resolve(false) | ||
} | ||
if (canUseBrowserCrypto != null) { | ||
return Promise.resolve(canUseBrowserCrypto) | ||
} | ||
var zeroBuffy = Buffer.alloc(32, 0) | ||
var ivFaith = Buffer.alloc(12, 0) | ||
return subtle.importKey('raw', zeroBuffy.buffer, { name: 'AES-GCM' }, true, ['encrypt']) | ||
.then(function (key) { | ||
return subtle.encrypt( | ||
{ name: 'AES-GCM', iv: ivFaith }, | ||
key, | ||
zeroBuffy.buffer | ||
) | ||
}) | ||
.then(function (response) { | ||
var buffy = Buffer.from(response) | ||
.then(function (res) { | ||
canUseBrowserCrypto = Buffer.from(res) | ||
.toString('base64') === 'zqdAPU1ga24HTsXTuvOdGHJgA8o3pip00aL1jnUGNY7R0whMmaqKn9q7PoPrKMFd' | ||
return { | ||
tag: buffy.slice(-16).toString('hex'), | ||
data: buffy.slice(0, -16).toString('hex') | ||
} | ||
return canUseBrowserCrypto | ||
}) | ||
.catch(function (err) { | ||
if (err.type === 'error' && err.data instanceof Error) { | ||
throw err.data | ||
} | ||
throw err | ||
.catch(function () { | ||
canUseBrowserCrypto = false | ||
return canUseBrowserCrypto | ||
}) | ||
} |
@@ -50,4 +50,3 @@ 'use strict' | ||
.catch(function (error) { | ||
console.warn("Couldn't pull docs from remote. Creating new salt!\nError: " + error) | ||
.catch(function () { | ||
return [] | ||
@@ -71,7 +70,2 @@ }) | ||
} | ||
console.warn( | ||
'Could not check the existence of a salt document on a remote db.\n' + | ||
'Please use the "remote" option when using "pouchdb-hoodie-api".' | ||
) | ||
return [] | ||
@@ -78,0 +72,0 @@ }) |
@@ -62,7 +62,2 @@ 'use strict' | ||
} | ||
console.warn( | ||
'Could not check the existence of a salt document on a remote db.\n' + | ||
'Please use the "remote" option when using "pouchdb-hoodie-api".' | ||
) | ||
return [] | ||
@@ -75,7 +70,6 @@ }) | ||
}, | ||
function (error) { | ||
function () { | ||
return store.find(['hoodiePluginCryptoStore/salt']) | ||
.then(function (result) { | ||
console.warn("Couldn't pull salt-docs from remote. Using local salt!\nError: " + error) | ||
return result | ||
@@ -82,0 +76,0 @@ }) |
@@ -5,4 +5,2 @@ // select the web crypto API | ||
var msrCryptoPolyfill = require('./msrcrypto') | ||
var globalContext = (function () { | ||
@@ -34,3 +32,3 @@ try { | ||
if (globalContext == null) { | ||
return msrCryptoPolyfill | ||
return null | ||
} | ||
@@ -46,3 +44,3 @@ | ||
} | ||
return msrCryptoPolyfill | ||
return null | ||
} |
{ | ||
"name": "hoodie-plugin-store-crypto", | ||
"version": "4.1.1", | ||
"version": "4.1.2", | ||
"description": "End-to-end crypto plugin for the Hoodie client store.", | ||
@@ -52,3 +52,5 @@ "main": "index.js", | ||
"browserify": "^17.0.0", | ||
"browserify-aes": "^1.2.0", | ||
"hoodie": "^28.2.10", | ||
"pbkdf2": "^3.1.1", | ||
"pouchdb-adapter-memory": "^7.2.2", | ||
@@ -58,6 +60,6 @@ "pouchdb-core": "^7.2.2", | ||
"pouchdb-replication": "^7.2.2", | ||
"puppeteer": "^5.4.1", | ||
"puppeteer": "^5.5.0", | ||
"puppeteer-firefox": "^0.5.1", | ||
"semantic-release": "^17.2.2", | ||
"snyk": "^1.425.4", | ||
"semantic-release": "^17.3.0", | ||
"snyk": "^1.431.2", | ||
"standard": "^14.3.4", | ||
@@ -75,3 +77,3 @@ "tap-spec": "^5.0.0", | ||
"@hoodie/store-client": "^8.3.0", | ||
"buffer": "^6.0.2", | ||
"buffer": "^6.0.3", | ||
"lie": "^3.3.0", | ||
@@ -78,0 +80,0 @@ "lodash": "^4.17.20", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
102919
21
50
2195
Updatedbuffer@^6.0.3