diff --git a/index.js b/index.js index debe651..fd9c42e 100644 --- a/index.js +++ b/index.js @@ -107,13 +107,13 @@ module.exports = { if (this.isHashable(data) && typeof(key)==='string') { let inputEncoding=my.INPUT_LIST.indexOf(input)>=0?input:my.INPUT // 'utf8' by default, 'ascii', 'latin1' for string or ignored for Buffer/TypedArray/DataView let outputEncoding=(output==='buf')?undefined:(my.OUTPUT_LIST.indexOf(output)>=0?output:my.OUTPUT) // 'latin1', 'base64', 'hex' by default or 'buf' to Buffer explicitly - let cipher=crypto.createCipher( + let ciph=crypto.createCipher( my.CIPHER_LIST.indexOf(cipher)>=0?cipher:my.CIPHER, this.hash(key)) if (typeof(data)!=='string' && !(data instanceof Buffer) && !(data instanceof DataView)) data=JSON.stringify(data) - let encrypted = cipher.update(data, inputEncoding, outputEncoding) - encrypted += cipher.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string + let encrypted = ciph.update(data, inputEncoding, outputEncoding) + encrypted += ciph.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string return encrypted } }else if (keytype==='pubkey') { // data 应当是 utf8 的字符串。// 但在浏览器里不能使用 Failed to execute 'encrypt' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView)' @@ -141,9 +141,13 @@ module.exports = { } } return decrypted - }else if (keytype==='seckey'){ // cipherobject 需要是 eccrypto 自身encrypt方法返回的对象 + } + }else if (keytype==='seckey'){ // cipherobject 需要是 eccrypto 自身encrypt方法返回的对象 + try { let plaindata = await eccrypto.decrypt(Buffer.from(key, 'hex'), data) // eccrypto 需要调用 Buffer.compare 方法,不能在这里直接用 hex2buf return plaindata.toString('utf8') + }catch (exception){ // eccrypto 对无法解密的,会抛出异常 + return null } } return null @@ -192,10 +196,11 @@ module.exports = { try { let result = await eccrypto.verify(Buffer.from(pubkey, 'hex'), this.hash(data, {output:'buf'}), Buffer.from(signature, 'hex')) // 如果给signature添加1位hex,eccrypto 的 verify结果也是true! 估计因为一位hex不被转成字节。 return true - }catch(exception){ + }catch(exception){ // 对能够验证的,eccrypto返回 null;对无法验证的,抛出异常 return false } } + return false } if (this.isHashable(data) && this.isSignature(signature) && this.isPubkey(pubkey) && signature.length===128){ // nacl option.output='buf' // 哈希必须输出为 buffer @@ -284,6 +289,24 @@ module.exports = { return null } , + seed2path(seed, {coin='TIC'}={coin:'TIC'}){ + // 路径规范 BIP44: m/Purpose'/Coin'/Account'/Change/Index, + // 但实际上 Purpose, Coin 都可任意定;' 可有可无; + // Account 最大到 parseInt(0x7FFFFFFF, 16), Coin/Index最大到 parseInt(0xFFFFFFFF, 16) + // 后面还可继续延伸 /xxx/xxx/xxx/...... let hash=this.hash(seed, {hasher:'md5'}) + let part0=parseInt(hash.slice(0,6), 16) + let part1=parseInt(hash.slice(6,12), 16) + let part2=parseInt(hash.slice(12,18), 16) + let part3=parseInt(hash.slice(18,24), 16) + let part4=parseInt(hash.slice(24,32), 16) + switch (coin){ + case 'BTC': return `m/44'/0'/${part0}'/${part1}/${part2}/${part3}/${part4}` + case 'ETH': return `m/44'/60'/${part0}'/${part1}/${part2}/${part3}/${part4}` + case 'TIC': + default: return `m/44'/66'/${part0}'/${part1}/${part2}/${part3}/${part4}` + } + } + , secword2account(secword, option){ // account 比 keypair 多了 address 字段。 option=option||{} option.coin=my.COIN_LIST.indexOf(option.coin)>=0?option.coin:my.COIN @@ -552,11 +575,9 @@ module.exports = { } , padStart(string, targetLength, symbol){ // 2020-03: 发现在浏览器里,还不支持 string.padStart(),只好自己写个暂代。 - let stringLength = string.length - if (stringLength < targetLength) { - for (let index = 1; index <= targetLength-stringLength; index++) { - string = symbol + string - } + let padLength = targetLength - string.length + for (let index = 1; index <= padLength; index++) { + string = symbol + string } return string }