fix(keystore):compatible with node 12

staking
neeboo 5 years ago
parent 6e1abec93b
commit ad01043bb0
  1. 2
      package.json
  2. 2
      packages/harmony-crypto/package.json
  3. 68
      packages/harmony-crypto/src/keystore.ts
  4. 12
      scripts/webpack/webpack.config.ts
  5. 2
      typings/scrypt.d.ts

@ -119,6 +119,7 @@
"rollup-plugin-node-resolve": "^3.4.0", "rollup-plugin-node-resolve": "^3.4.0",
"rollup-plugin-typescript2": "^0.17.1", "rollup-plugin-typescript2": "^0.17.1",
"solc": "^0.5.8", "solc": "^0.5.8",
"terser-webpack-plugin": "^2.1.2",
"ts-jest": "^23.1.3", "ts-jest": "^23.1.3",
"ts-node": "^7.0.1", "ts-node": "^7.0.1",
"tslint": "^5.11.0", "tslint": "^5.11.0",
@ -127,7 +128,6 @@
"typedoc-plugin-markdown": "^2.1.0", "typedoc-plugin-markdown": "^2.1.0",
"typescript": "^3.2", "typescript": "^3.2",
"typescript-json-schema": "^0.36.0", "typescript-json-schema": "^0.36.0",
"uglifyjs-webpack-plugin": "^2.1.2",
"webpack": "^4.20.2", "webpack": "^4.20.2",
"webpack-command": "^0.4.1", "webpack-command": "^0.4.1",
"webpack-node-externals": "^1.7.2", "webpack-node-externals": "^1.7.2",

@ -27,7 +27,7 @@
"hmac-drbg": "^1.0.1", "hmac-drbg": "^1.0.1",
"js-sha3": "^0.8.0", "js-sha3": "^0.8.0",
"pbkdf2": "^3.0.17", "pbkdf2": "^3.0.17",
"scrypt.js": "^0.3.0", "scrypt-shim": "github:web3-js/scrypt-shim",
"uuid": "^3.3.2" "uuid": "^3.3.2"
}, },
"gitHead": "775e2ba36924fcffd8d2c0b73587b549ed90bb81" "gitHead": "775e2ba36924fcffd8d2c0b73587b549ed90bb81"

@ -1,5 +1,6 @@
import aes from 'aes-js'; import aes from 'aes-js';
import scrypt from 'scrypt.js'; // import scrypt from 'scrypt.js';
import scrypt from 'scrypt-shim';
import { pbkdf2Sync } from 'pbkdf2'; import { pbkdf2Sync } from 'pbkdf2';
import uuid from 'uuid'; import uuid from 'uuid';
import { isPrivateKey } from '@harmony-js/utils'; import { isPrivateKey } from '@harmony-js/utils';
@ -7,14 +8,7 @@ import { randomBytes } from './random';
import { getAddressFromPrivateKey } from './keyTool'; import { getAddressFromPrivateKey } from './keyTool';
import { concat, hexToIntArray } from './bytes'; import { concat, hexToIntArray } from './bytes';
import { keccak256 } from './keccak256'; import { keccak256 } from './keccak256';
import { import { KDF, KDFParams, EncryptOptions, PBKDF2Params, ScryptParams, Keystore } from './types';
KDF,
KDFParams,
EncryptOptions,
PBKDF2Params,
ScryptParams,
Keystore,
} from './types';
const DEFAULT_ALGORITHM = 'aes-128-ctr'; const DEFAULT_ALGORITHM = 'aes-128-ctr';
@ -29,11 +23,7 @@ const DEFAULT_ALGORITHM = 'aes-128-ctr';
* *
* @returns {Promise<Buffer>} * @returns {Promise<Buffer>}
*/ */
async function getDerivedKey( async function getDerivedKey(key: Buffer, kdf: KDF, params: KDFParams): Promise<Buffer> {
key: Buffer,
kdf: KDF,
params: KDFParams,
): Promise<Buffer> {
const salt = Buffer.from(params.salt, 'hex'); const salt = Buffer.from(params.salt, 'hex');
if (kdf === 'pbkdf2') { if (kdf === 'pbkdf2') {
@ -77,10 +67,8 @@ export const encrypt = async (
const salt = randomBytes(32); const salt = randomBytes(32);
const iv = Buffer.from(randomBytes(16), 'hex'); const iv = Buffer.from(randomBytes(16), 'hex');
const kdf = const kdf = options !== undefined ? (options.kdf ? options.kdf : 'scrypt') : 'scrypt';
options !== undefined ? (options.kdf ? options.kdf : 'scrypt') : 'scrypt'; const level = options !== undefined ? (options.level ? options.level : 8192) : 8192;
const level =
options !== undefined ? (options.level ? options.level : 8192) : 8192;
const uuidRandom = options !== undefined ? options.uuid : undefined; const uuidRandom = options !== undefined ? options.uuid : undefined;
@ -94,18 +82,13 @@ export const encrypt = async (
}; };
const derivedKey = await getDerivedKey(Buffer.from(password), kdf, kdfparams); const derivedKey = await getDerivedKey(Buffer.from(password), kdf, kdfparams);
const cipher = new aes.ModeOfOperation.ctr( const cipher = new aes.ModeOfOperation.ctr(derivedKey.slice(0, 16), new aes.Counter(iv));
derivedKey.slice(0, 16),
new aes.Counter(iv),
);
if (!cipher) { if (!cipher) {
throw new Error('Unsupported cipher'); throw new Error('Unsupported cipher');
} }
const ciphertext = Buffer.from( const ciphertext = Buffer.from(cipher.encrypt(Buffer.from(privateKey.replace('0x', ''), 'hex')));
cipher.encrypt(Buffer.from(privateKey.replace('0x', ''), 'hex')),
);
const mac = keccak256(concat([derivedKey.slice(16, 32), ciphertext])); const mac = keccak256(concat([derivedKey.slice(16, 32), ciphertext]));
@ -132,24 +115,14 @@ export const encrypt = async (
* @param {string} password - password string * @param {string} password - password string
* @return {string} privateKey * @return {string} privateKey
*/ */
export const decrypt = async ( export const decrypt = async (keystore: Keystore, password: string): Promise<string> => {
keystore: Keystore,
password: string,
): Promise<string> => {
const ciphertext = Buffer.from(keystore.Crypto.ciphertext, 'hex'); const ciphertext = Buffer.from(keystore.Crypto.ciphertext, 'hex');
const iv = Buffer.from(keystore.Crypto.cipherparams.iv, 'hex'); const iv = Buffer.from(keystore.Crypto.cipherparams.iv, 'hex');
const { kdfparams } = keystore.Crypto; const { kdfparams } = keystore.Crypto;
const derivedKey = await getDerivedKey( const derivedKey = await getDerivedKey(Buffer.from(password), keystore.Crypto.kdf, kdfparams);
Buffer.from(password),
keystore.Crypto.kdf,
kdfparams,
);
const mac = keccak256(concat([derivedKey.slice(16, 32), ciphertext])).replace( const mac = keccak256(concat([derivedKey.slice(16, 32), ciphertext])).replace('0x', '');
'0x',
'',
);
if (mac.toUpperCase() !== keystore.Crypto.mac.toUpperCase()) { if (mac.toUpperCase() !== keystore.Crypto.mac.toUpperCase()) {
return Promise.reject(new Error('Failed to decrypt.')); return Promise.reject(new Error('Failed to decrypt.'));
@ -159,8 +132,7 @@ export const decrypt = async (
const cipher = new CTR(derivedKey.slice(0, 16), new aes.Counter(iv)); const cipher = new CTR(derivedKey.slice(0, 16), new aes.Counter(iv));
const decrypted = const decrypted = '0x' + Buffer.from(cipher.decrypt(ciphertext)).toString('hex');
'0x' + Buffer.from(cipher.decrypt(ciphertext)).toString('hex');
return decrypted; return decrypted;
}; };
@ -174,10 +146,8 @@ export const encryptPhrase = async (
} }
const salt = randomBytes(32); const salt = randomBytes(32);
const iv = Buffer.from(randomBytes(16), 'hex'); const iv = Buffer.from(randomBytes(16), 'hex');
const kdf = const kdf = options !== undefined ? (options.kdf ? options.kdf : 'scrypt') : 'scrypt';
options !== undefined ? (options.kdf ? options.kdf : 'scrypt') : 'scrypt'; const level = options !== undefined ? (options.level ? options.level : 8192) : 8192;
const level =
options !== undefined ? (options.level ? options.level : 8192) : 8192;
const uuidRandom = options !== undefined ? options.uuid : undefined; const uuidRandom = options !== undefined ? options.uuid : undefined;
@ -190,10 +160,7 @@ export const encryptPhrase = async (
dklen: 32, dklen: 32,
}; };
const derivedKey = await getDerivedKey(Buffer.from(password), kdf, kdfparams); const derivedKey = await getDerivedKey(Buffer.from(password), kdf, kdfparams);
const cipher = new aes.ModeOfOperation.ctr( const cipher = new aes.ModeOfOperation.ctr(derivedKey.slice(0, 16), new aes.Counter(iv));
derivedKey.slice(0, 16),
new aes.Counter(iv),
);
if (!cipher) { if (!cipher) {
throw new Error('Unsupported cipher'); throw new Error('Unsupported cipher');
@ -218,10 +185,7 @@ export const encryptPhrase = async (
}); });
}; };
export const decryptPhrase = async ( export const decryptPhrase = async (keystore: Keystore, password: string): Promise<string> => {
keystore: Keystore,
password: string,
): Promise<string> => {
const result = await decrypt(keystore, password); const result = await decrypt(keystore, password);
return Buffer.from(result.replace('0x', ''), 'hex').toString(); return Buffer.from(result.replace('0x', ''), 'hex').toString();
}; };

@ -1,13 +1,13 @@
import path from 'path'; import path from 'path';
// tslint:disable-next-line: no-implicit-dependencies // tslint:disable-next-line: no-implicit-dependencies
import UglifyJs from 'uglifyjs-webpack-plugin'; import TerserPlugin from 'terser-webpack-plugin';
// tslint:disable-next-line: no-implicit-dependencies // tslint:disable-next-line: no-implicit-dependencies
import {Configuration} from 'webpack'; import { Configuration } from 'webpack';
// // tslint:disable-next-line: no-implicit-dependencies // // tslint:disable-next-line: no-implicit-dependencies
// import {createVariants} from 'parallel-webpack'; // import {createVariants} from 'parallel-webpack';
import {packageList, PackageItem} from './packagesForWP'; import { packageList, PackageItem } from './packagesForWP';
function createBatchConfig(list: PackageItem[]) { function createBatchConfig(list: PackageItem[]) {
return list.map((l: PackageItem) => { return list.map((l: PackageItem) => {
@ -37,9 +37,11 @@ function createBatchConfig(list: PackageItem[]) {
const batchClientConfig = { const batchClientConfig = {
...batchBaseConfig, ...batchBaseConfig,
optimization: { optimization: {
minimize: true,
minimizer: [ minimizer: [
new UglifyJs({ new TerserPlugin({
uglifyOptions: { terserOptions: {
ecma: 6,
compress: true, compress: true,
mangle: true, mangle: true,
toplevel: false, toplevel: false,

@ -1,4 +1,4 @@
declare module 'scrypt.js' { declare module 'scrypt-shim' {
export default function scrypt( export default function scrypt(
key: Buffer, key: Buffer,
salt: Buffer, salt: Buffer,

Loading…
Cancel
Save