New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@metamask/browser-passworder

Package Overview
Dependencies
Maintainers
8
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@metamask/browser-passworder - npm Package Compare versions

Comparing version 3.0.0 to 4.0.1

132

dist/index.d.ts

@@ -1,6 +0,15 @@

interface EncryptionResult {
declare type DetailedEncryptionResult = {
vault: string;
exportedKeyString: string;
};
declare type EncryptionResult = {
data: string;
iv: string;
salt?: string;
}
};
declare type DetailedDecryptResult = {
exportedKeyString: string;
vault: unknown;
salt: string;
};
/**

@@ -10,64 +19,101 @@ * Encrypts a data object that can be any serializable value using

*
* @param {string} password - password to use for encryption
* @param {R} dataObj - data to encrypt
* @returns {Promise<string>} cypher text
* @param password - The password to use for encryption.
* @param dataObj - The data to encrypt.
* @param key - The CryptoKey to encrypt with.
* @param salt - The salt to use to encrypt.
* @returns The encrypted vault.
*/
declare function encrypt<R>(password: string, dataObj: R): Promise<string>;
export declare function encrypt<R>(password: string, dataObj: R, key?: CryptoKey, salt?: string): Promise<string>;
/**
* Encrypts a data object that can be any serializable value using
* a provided password.
*
* @param password - A password to use for encryption.
* @param dataObj - The data to encrypt.
* @param salt - The salt used to encrypt.
* @returns The vault and exported key string.
*/
export declare function encryptWithDetail<R>(password: string, dataObj: R, salt?: string): Promise<DetailedEncryptionResult>;
/**
* Encrypts the provided serializable javascript object using the
* provided CryptoKey and returns an object containing the cypher text and
* the initialization vector used.
* @param {CryptoKey} key - CryptoKey to encrypt with
* @param {R} dataObj - Serializable javascript object to encrypt
* @returns {EncryptionResult}
*
* @param key - The CryptoKey to encrypt with.
* @param dataObj - A serializable JavaScript object to encrypt.
* @returns The encrypted data.
*/
declare function encryptWithKey<R>(key: CryptoKey, dataObj: R): Promise<EncryptionResult>;
export declare function encryptWithKey<R>(key: CryptoKey, dataObj: R): Promise<EncryptionResult>;
/**
* Given a password and a cypher text, decrypts the text and returns
* the resulting value
* @param {string} password - password to decrypt with
* @param {string} text - cypher text to decrypt
* the resulting value.
*
* @param password - The password to decrypt with.
* @param text - The cypher text to decrypt.
* @param key - The key to decrypt with.
* @returns The decrypted data.
*/
declare function decrypt<R>(password: string, text: string): Promise<R>;
export declare function decrypt(password: string, text: string, key?: CryptoKey): Promise<unknown>;
/**
* Given a password and a cypher text, decrypts the text and returns
* the resulting value, keyString, and salt.
*
* @param password - The password to decrypt with.
* @param text - The encrypted vault to decrypt.
* @returns The decrypted vault along with the salt and exported key.
*/
export declare function decryptWithDetail(password: string, text: string): Promise<DetailedDecryptResult>;
/**
* Given a CryptoKey and an EncryptionResult object containing the initialization
* vector (iv) and data to decrypt, return the resulting decrypted value.
* @param {CryptoKey} key - CryptoKey to decrypt with
* @param {EncryptionResult} payload - payload returned from an encryption method
*
* @param key - The CryptoKey to decrypt with.
* @param payload - The payload to decrypt, returned from an encryption method.
* @returns The decrypted data.
*/
declare function decryptWithKey<R>(key: CryptoKey, payload: EncryptionResult): Promise<R>;
export declare function decryptWithKey<R>(key: CryptoKey, payload: EncryptionResult): Promise<R>;
/**
* Generate a CryptoKey from a password and random salt
* @param {string} password - The password to use to generate key
* @param {string} salt - The salt string to use in key derivation
* Receives an exported CryptoKey string and creates a key.
*
* @param keyString - The key string to import.
* @returns A CryptoKey.
*/
declare function keyFromPassword(password: string, salt: string): Promise<CryptoKey>;
export declare function importKey(keyString: string): Promise<CryptoKey>;
/**
* Receives an exported CryptoKey string, creates a key,
* and decrypts cipher text with the reconstructed key.
*
* @param key - The CryptoKey to export.
* @returns A key string.
*/
export declare function exportKey(key: CryptoKey): Promise<string>;
/**
* Generate a CryptoKey from a password and random salt.
*
* @param password - The password to use to generate key.
* @param salt - The salt string to use in key derivation.
* @returns A CryptoKey for encryption and decryption.
*/
export declare function keyFromPassword(password: string, salt: string): Promise<CryptoKey>;
/**
* Converts a hex string into a buffer.
* @param {string} str - hex encoded string
* @returns {Uint8Array}
*
* @param str - Hex encoded string.
* @returns The string ecoded as a byte array.
*/
declare function serializeBufferFromStorage(str: string): Uint8Array;
export declare function serializeBufferFromStorage(str: string): Uint8Array;
/**
* Converts a buffer into a hex string ready for storage
* @param {Uint8Array} buffer - Buffer to serialize
* @returns {string} hex encoded string
* Converts a buffer into a hex string ready for storage.
*
* @param buffer - Buffer to serialize.
* @returns A hex encoded string.
*/
declare function serializeBufferForStorage(buffer: Uint8Array): string;
export declare function serializeBufferForStorage(buffer: Uint8Array): string;
/**
* Generates a random string for use as a salt in CryptoKey generation
* @param {number} byteCount - Number of bytes to generate
* @returns {string} randomly generated string
* Generates a random string for use as a salt in CryptoKey generation.
*
* @param byteCount - The number of bytes to generate.
* @returns A randomly generated string.
*/
declare function generateSalt(byteCount?: number): string;
declare const _default: {
encrypt: typeof encrypt;
decrypt: typeof decrypt;
keyFromPassword: typeof keyFromPassword;
encryptWithKey: typeof encryptWithKey;
decryptWithKey: typeof decryptWithKey;
serializeBufferForStorage: typeof serializeBufferForStorage;
serializeBufferFromStorage: typeof serializeBufferFromStorage;
generateSalt: typeof generateSalt;
};
export = _default;
export declare function generateSalt(byteCount?: number): string;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateSalt = exports.serializeBufferForStorage = exports.serializeBufferFromStorage = exports.keyFromPassword = exports.exportKey = exports.importKey = exports.decryptWithKey = exports.decryptWithDetail = exports.decrypt = exports.encryptWithKey = exports.encryptWithDetail = exports.encrypt = void 0;
const EXPORT_FORMAT = 'jwk';
const DERIVED_KEY_FORMAT = 'AES-GCM';
const STRING_ENCODING = 'utf-8';
/**

@@ -6,104 +11,170 @@ * Encrypts a data object that can be any serializable value using

*
* @param {string} password - password to use for encryption
* @param {R} dataObj - data to encrypt
* @returns {Promise<string>} cypher text
* @param password - The password to use for encryption.
* @param dataObj - The data to encrypt.
* @param key - The CryptoKey to encrypt with.
* @param salt - The salt to use to encrypt.
* @returns The encrypted vault.
*/
function encrypt(password, dataObj) {
const salt = generateSalt();
return keyFromPassword(password, salt)
.then(function (passwordDerivedKey) {
return encryptWithKey(passwordDerivedKey, dataObj);
})
.then(function (payload) {
payload.salt = salt;
return JSON.stringify(payload);
});
async function encrypt(password, dataObj, key, salt = generateSalt()) {
const cryptoKey = key || (await keyFromPassword(password, salt));
const payload = await encryptWithKey(cryptoKey, dataObj);
payload.salt = salt;
return JSON.stringify(payload);
}
exports.encrypt = encrypt;
/**
* Encrypts a data object that can be any serializable value using
* a provided password.
*
* @param password - A password to use for encryption.
* @param dataObj - The data to encrypt.
* @param salt - The salt used to encrypt.
* @returns The vault and exported key string.
*/
async function encryptWithDetail(password, dataObj, salt = generateSalt()) {
const key = await keyFromPassword(password, salt);
const exportedKeyString = await exportKey(key);
const vault = await encrypt(password, dataObj, key, salt);
return {
vault,
exportedKeyString,
};
}
exports.encryptWithDetail = encryptWithDetail;
/**
* Encrypts the provided serializable javascript object using the
* provided CryptoKey and returns an object containing the cypher text and
* the initialization vector used.
* @param {CryptoKey} key - CryptoKey to encrypt with
* @param {R} dataObj - Serializable javascript object to encrypt
* @returns {EncryptionResult}
*
* @param key - The CryptoKey to encrypt with.
* @param dataObj - A serializable JavaScript object to encrypt.
* @returns The encrypted data.
*/
function encryptWithKey(key, dataObj) {
async function encryptWithKey(key, dataObj) {
const data = JSON.stringify(dataObj);
const dataBuffer = Buffer.from(data, 'utf-8');
const dataBuffer = Buffer.from(data, STRING_ENCODING);
const vector = global.crypto.getRandomValues(new Uint8Array(16));
return global.crypto.subtle
.encrypt({
name: 'AES-GCM',
const buf = await global.crypto.subtle.encrypt({
name: DERIVED_KEY_FORMAT,
iv: vector,
}, key, dataBuffer)
.then(function (buf) {
const buffer = new Uint8Array(buf);
const vectorStr = Buffer.from(vector).toString('base64');
const vaultStr = Buffer.from(buffer).toString('base64');
return {
data: vaultStr,
iv: vectorStr,
};
});
}, key, dataBuffer);
const buffer = new Uint8Array(buf);
const vectorStr = Buffer.from(vector).toString('base64');
const vaultStr = Buffer.from(buffer).toString('base64');
return {
data: vaultStr,
iv: vectorStr,
};
}
exports.encryptWithKey = encryptWithKey;
/**
* Given a password and a cypher text, decrypts the text and returns
* the resulting value
* @param {string} password - password to decrypt with
* @param {string} text - cypher text to decrypt
* the resulting value.
*
* @param password - The password to decrypt with.
* @param text - The cypher text to decrypt.
* @param key - The key to decrypt with.
* @returns The decrypted data.
*/
function decrypt(password, text) {
async function decrypt(password, text, key) {
const payload = JSON.parse(text);
const { salt } = payload;
return keyFromPassword(password, salt).then(function (key) {
return decryptWithKey(key, payload);
});
const cryptoKey = key || (await keyFromPassword(password, salt));
const result = await decryptWithKey(cryptoKey, payload);
return result;
}
exports.decrypt = decrypt;
/**
* Given a password and a cypher text, decrypts the text and returns
* the resulting value, keyString, and salt.
*
* @param password - The password to decrypt with.
* @param text - The encrypted vault to decrypt.
* @returns The decrypted vault along with the salt and exported key.
*/
async function decryptWithDetail(password, text) {
const payload = JSON.parse(text);
const { salt } = payload;
const key = await keyFromPassword(password, salt);
const exportedKeyString = await exportKey(key);
const vault = await decrypt(password, text, key);
return {
exportedKeyString,
vault,
salt,
};
}
exports.decryptWithDetail = decryptWithDetail;
/**
* Given a CryptoKey and an EncryptionResult object containing the initialization
* vector (iv) and data to decrypt, return the resulting decrypted value.
* @param {CryptoKey} key - CryptoKey to decrypt with
* @param {EncryptionResult} payload - payload returned from an encryption method
*
* @param key - The CryptoKey to decrypt with.
* @param payload - The payload to decrypt, returned from an encryption method.
* @returns The decrypted data.
*/
function decryptWithKey(key, payload) {
async function decryptWithKey(key, payload) {
const encryptedData = Buffer.from(payload.data, 'base64');
const vector = Buffer.from(payload.iv, 'base64');
return crypto.subtle
.decrypt({ name: 'AES-GCM', iv: vector }, key, encryptedData)
.then(function (result) {
let decryptedObj;
try {
const result = await crypto.subtle.decrypt({ name: DERIVED_KEY_FORMAT, iv: vector }, key, encryptedData);
const decryptedData = new Uint8Array(result);
const decryptedStr = Buffer.from(decryptedData).toString('utf-8');
const decryptedObj = JSON.parse(decryptedStr);
return decryptedObj;
})
.catch(function (_error) {
const decryptedStr = Buffer.from(decryptedData).toString(STRING_ENCODING);
decryptedObj = JSON.parse(decryptedStr);
}
catch (e) {
throw new Error('Incorrect password');
});
}
return decryptedObj;
}
exports.decryptWithKey = decryptWithKey;
/**
* Generate a CryptoKey from a password and random salt
* @param {string} password - The password to use to generate key
* @param {string} salt - The salt string to use in key derivation
* Receives an exported CryptoKey string and creates a key.
*
* @param keyString - The key string to import.
* @returns A CryptoKey.
*/
function keyFromPassword(password, salt) {
const passBuffer = Buffer.from(password, 'utf-8');
async function importKey(keyString) {
const key = await window.crypto.subtle.importKey(EXPORT_FORMAT, JSON.parse(keyString), DERIVED_KEY_FORMAT, true, ['encrypt', 'decrypt']);
return key;
}
exports.importKey = importKey;
/**
* Receives an exported CryptoKey string, creates a key,
* and decrypts cipher text with the reconstructed key.
*
* @param key - The CryptoKey to export.
* @returns A key string.
*/
async function exportKey(key) {
const exportedKey = await window.crypto.subtle.exportKey(EXPORT_FORMAT, key);
return JSON.stringify(exportedKey);
}
exports.exportKey = exportKey;
/**
* Generate a CryptoKey from a password and random salt.
*
* @param password - The password to use to generate key.
* @param salt - The salt string to use in key derivation.
* @returns A CryptoKey for encryption and decryption.
*/
async function keyFromPassword(password, salt) {
const passBuffer = Buffer.from(password, STRING_ENCODING);
const saltBuffer = Buffer.from(salt, 'base64');
return global.crypto.subtle
.importKey('raw', passBuffer, { name: 'PBKDF2' }, false, [
'deriveBits',
'deriveKey',
])
.then(function (key) {
return global.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt: saltBuffer,
iterations: 10000,
hash: 'SHA-256',
}, key, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
});
const key = await global.crypto.subtle.importKey('raw', passBuffer, { name: 'PBKDF2' }, false, ['deriveBits', 'deriveKey']);
const derivedKey = await global.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt: saltBuffer,
iterations: 10000,
hash: 'SHA-256',
}, key, { name: DERIVED_KEY_FORMAT, length: 256 }, true, ['encrypt', 'decrypt']);
return derivedKey;
}
exports.keyFromPassword = keyFromPassword;
/**
* Converts a hex string into a buffer.
* @param {string} str - hex encoded string
* @returns {Uint8Array}
*
* @param str - Hex encoded string.
* @returns The string ecoded as a byte array.
*/

@@ -119,20 +190,23 @@ function serializeBufferFromStorage(str) {

}
exports.serializeBufferFromStorage = serializeBufferFromStorage;
/**
* Converts a buffer into a hex string ready for storage
* @param {Uint8Array} buffer - Buffer to serialize
* @returns {string} hex encoded string
* Converts a buffer into a hex string ready for storage.
*
* @param buffer - Buffer to serialize.
* @returns A hex encoded string.
*/
function serializeBufferForStorage(buffer) {
let result = '0x';
const len = buffer.length || buffer.byteLength;
for (let i = 0; i < len; i++) {
result += unprefixedHex(buffer[i]);
}
buffer.forEach((value) => {
result += unprefixedHex(value);
});
return result;
}
exports.serializeBufferForStorage = serializeBufferForStorage;
/**
* Converts a number into hex value, and ensures proper leading 0
* for single characters strings.
* @param {number} num - number to convert to string
* @returns {string} hex string
*
* @param num - The number to convert to string.
* @returns An unprefixed hex string.
*/

@@ -147,5 +221,6 @@ function unprefixedHex(num) {

/**
* Generates a random string for use as a salt in CryptoKey generation
* @param {number} byteCount - Number of bytes to generate
* @returns {string} randomly generated string
* Generates a random string for use as a salt in CryptoKey generation.
*
* @param byteCount - The number of bytes to generate.
* @returns A randomly generated string.
*/

@@ -163,15 +238,3 @@ function generateSalt(byteCount = 32) {

}
module.exports = {
// Simple encryption methods:
encrypt,
decrypt,
// More advanced encryption methods:
keyFromPassword,
encryptWithKey,
decryptWithKey,
// Buffer <-> Hex string methods
serializeBufferForStorage,
serializeBufferFromStorage,
generateSalt,
};
exports.generateSalt = generateSalt;
//# sourceMappingURL=index.js.map
{
"name": "@metamask/browser-passworder",
"version": "3.0.0",
"version": "4.0.1",
"description": "A simple browserifiable module for password-encrypting JS objects.",

@@ -30,33 +30,38 @@ "keywords": [

"scripts": {
"setup": "yarn install && yarn allow-scripts",
"build": "tsc",
"test": "testem ci -P 2",
"buildTest": "yarn build && browserify test/index.js -o test/bundle.js",
"build": "tsc --project tsconfig.build.json",
"build:clean": "rimraf dist && yarn build",
"buildTest": "yarn build && browserify dist/index.js --standalone encryptor -o test/bundle.js",
"lint": "yarn lint:eslint && yarn lint:misc --check",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore",
"lint": "yarn lint:eslint && yarn lint:misc --check",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write"
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern",
"prepack": "./scripts/prepack.sh",
"test": "yarn buildTest && playwright test"
},
"devDependencies": {
"@lavamoat/allow-scripts": "^1.0.6",
"@metamask/auto-changelog": "^2.4.0",
"@metamask/eslint-config": "^7.0.1",
"@metamask/eslint-config-nodejs": "^7.0.1",
"@metamask/eslint-config-typescript": "^7.0.1",
"@lavamoat/allow-scripts": "^2.0.3",
"@metamask/auto-changelog": "^2.6.1",
"@metamask/eslint-config": "^10.0.0",
"@metamask/eslint-config-nodejs": "^10.0.0",
"@metamask/eslint-config-typescript": "^10.0.0",
"@playwright/test": "^1.27.1",
"@types/node": "^14.14.5",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.1",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
"browserify": "^17.0.0",
"eslint": "^7.29.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4",
"eslint": "^8.26.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^39.3.25",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"prettier": "^2.3.2",
"prettier-plugin-packagejson": "^2.2.11",
"testem": "^3.4.2",
"typescript": "^4.3.4"
"eslint-plugin-prettier": "^4.2.1",
"playwright": "^1.27.1",
"prettier": "^2.7.1",
"prettier-plugin-packagejson": "^2.3.0",
"rimraf": "^3.0.2",
"typescript": "^4.8.4"
},
"packageManager": "yarn@3.2.4",
"engines": {
"node": ">=12.0.0"
"node": ">=14.0.0"
},

@@ -69,5 +74,6 @@ "publishConfig": {

"allowScripts": {
"@lavamoat/preinstall-always-fail": false
"@lavamoat/preinstall-always-fail": false,
"playwright": true
}
}
}

@@ -14,3 +14,3 @@ # Browser Passworder

```bash
yarn install @metamask/browser-passworder
yarn add @metamask/browser-passworder
```

@@ -43,5 +43,6 @@

The serialized text is stored as a JSON blob that includes two base64-encoded fields, `data` and `iv`, neither of which you need to worry about.
The serialized text is stored as a JSON blob that includes three base64-encoded fields, `data`, `iv`, and `salt`, none of which you need to worry about.
The data is encrypted using the `AES-GCM` algorithm. It is salted with the result of `crypto.getRandomValues()`, and the encryption vector is generated the same way.
A key is derived from the password using `PBKDF2` with a salt sampled from `crypto.getRandomValues()`.
The data is encrypted using the `AES-GCM` algorithm with an initialization vector sampled from `crypto.getRandomValues()`.

@@ -52,7 +53,6 @@ ## Contributing

- Install [Node.js](https://nodejs.org) version 12
- Install [Node.js](https://nodejs.org) version 14
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
- Install [Yarn v1](https://yarnpkg.com/en/docs/install)
- Run `yarn setup` to install dependencies and run any requried post-install scripts
- **Warning:** Do not use the `yarn` / `yarn install` command directly. Use `yarn setup` instead. The normal install command will skip required post-install scripts, leaving your development environment in an invalid state.
- Install [Yarn v3](https://yarnpkg.com/getting-started/install)
- Run `yarn install` to install dependencies and run any required post-install scripts

@@ -59,0 +59,0 @@ ### Testing and Linting

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc