diff --git a/test.js b/test.js index 6402aa7..cf6c1ab 100644 --- a/test.js +++ b/test.js @@ -94,8 +94,8 @@ console.log('address = ', add) /////////////////////// keyutil -let seckeyObject = new keyutil.Key('oct', Buffer.from(acc.seckey, 'hex'), { namedCurve: 'P-256K' }) // {P-256 : secp256r1, P-384 : secp384r1, P-521 : secp521r1, P-256K : secp256k1} -let seckeyObject2 = new keyutil.Key('oct', tic.hex_to_buf(acc.seckey, 'hex'), { namedCurve: 'P-256K' }) +let seckeyObject = new keyutil.Key('oct', Buffer.from(acc.prikey, 'hex'), { namedCurve: 'P-256K' }) // {P-256 : secp256r1, P-384 : secp384r1, P-521 : secp521r1, P-256K : secp256k1} +let seckeyObject2 = new keyutil.Key('oct', tic.hex_to_buf(acc.prikey, 'hex'), { namedCurve: 'P-256K' }) let seckeyPEM seckeyObject.export('pem').then((data) => (seckeyPEM = data)) let seckeyDER @@ -124,17 +124,17 @@ verifyKU.end() var verified = verifyKU.verify(pubkeyPEM, signatureKU) // specify format in [pem,der] and type in [pkcs1,spki] console.log('verified = ', verified) // 可以验证通过,但是用的privatekey,没有成功使用publickey。 -crypto.createCipheriv('aes-256-cfb', Buffer.from(acc.seckey, 'hex'), Buffer.alloc(16)) +crypto.createCipheriv('aes-256-cfb', Buffer.from(acc.prikey, 'hex'), Buffer.alloc(16)) ////////////////////// crypto + PEM toPEM = function (kp) { let pubkey = crypto .createECDH('secp256k1') - .setPrivateKey(kp.seckey, 'hex') + .setPrivateKey(kp.prikey, 'hex') .getPublicKey('hex', 'compressed') console.log('ECDH created publickey = ', pubkey) - let mykey = '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420' + kp.seckey + 'a144034200' + pubkey + let mykey = '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420' + kp.prikey + 'a144034200' + pubkey console.log(mykey) let privKey = '-----BEGIN PRIVATE KEY-----\n' + Buffer.from(mykey, 'hex').toString('base64') + '\n-----END PRIVATE KEY-----' // pubKey2 = crypto.createPublicKey(privKey); //也可恢复出公钥。测试不成功。 @@ -156,7 +156,7 @@ console.log('pemKP = ', pemKP) // https://www.shangyang.me/2017/05/24/encrypt-rsa-keyformat/ var buf1 = Buffer.from('308141020100301306072a8648ce3d020106082a8648ce3d030107042730250201010420', 'hex') // specific byte-sequence for curve prime256v1 -var buf2 = Buffer.from(acc.seckey, 'hex') // raw private key (32 bytes) +var buf2 = Buffer.from(acc.prikey, 'hex') // raw private key (32 bytes) var privateKeyPkcs8Der = Buffer.concat([buf1, buf2], buf1.length + buf2.length) var sign = crypto.createSign('sha256') sign.write('毛主席万岁') @@ -186,7 +186,7 @@ var EC = require('elliptic').ec var ec = new EC('secp256k1') // Generate keys //var key = ec.genKeyPair(); -var key = ec.keyFromPrivate(acc.seckey) // 注意,不需要 'hex' 参数 +var key = ec.keyFromPrivate(acc.prikey) // 注意,不需要 'hex' 参数 // Sign the message's hash (input must be an array, or a hex-string) var msgHash = tic.hash('毛主席万岁') var msgHashBad = tic.hash('毛主席万岁 ') diff --git a/ticc.js b/ticc.js index 0d0f81f..e0434b2 100644 --- a/ticc.js +++ b/ticc.js @@ -138,14 +138,14 @@ class TicCrypto { * 测试是否合法的私钥 * * @static - * @param {String} seckey + * @param {String} prikey * @return {Boolean} * @memberof TicCrypto */ - static is_seckey ({ seckey } = {}) { + static is_seckey ({ prikey } = {}) { // 比特币、以太坊的私钥:64 hex // nacl.sign 的私钥 128 hex, nacl.box 的私钥 64 hex - return /^([a-fA-F0-9]{128}|[a-fA-F0-9]{64})$/.test(seckey) + return /^([a-fA-F0-9]{128}|[a-fA-F0-9]{64})$/.test(prikey) } /** @@ -228,7 +228,7 @@ class TicCrypto { ciphertext += encryptor.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string return { iv: iv.toString('hex'), ciphertext } // 有 iv,显然每次结果不一样 } - } else if (keytype === 'seckey') { + } else if (keytype === 'prikey') { // 尚未走通,不能使用 ticc 生成的 Elliptic curve 椭圆曲线算法公私钥,只能用 crypto.generateKeyPairSync('rsa') 生成的 rsa 公私钥 let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(key), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。 return crypto.privateEncrypt(seckeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果都一样。 @@ -272,7 +272,7 @@ class TicCrypto { // 如果用户输入错误密码,deciper也能解密,无法自动判断是否正确结果。可在返回后人工判断。 return decrypted } - } else if (keytype === 'seckey') { + } else if (keytype === 'prikey') { // 尚未走通,不能使用 ticc 生成的 Elliptic curve 椭圆曲线算法公私钥 let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(key), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。 return crypto.privateDecrypt(seckeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果都一样。 @@ -288,26 +288,26 @@ class TicCrypto { * * @static * @param {*} data - * @param {String} seckey + * @param {String} prikey * @param {Object} option [option={}] * @return {String} * @memberof TicCrypto */ - static async sign_easy ({ data, seckey, tool = 'crypto', hasher = my.HASHER }) { + static async sign_easy ({ data, prikey, tool = 'crypto', hasher = my.HASHER }) { // data can be string or buffer or object, results are the same - if (this.is_hashable({ data }) && this.is_seckey({ seckey })) { - if (tool === 'nacl' && seckey.length === 128) { + if (this.is_hashable({ data }) && this.is_seckey({ prikey })) { + if (tool === 'nacl' && prikey.length === 128) { // 使用nacl的签名算法。注意,nacl.sign需要的seckey是64字节=128字符。 let hashBuf = this.hash_easy(data, { output: 'buf' }) // 哈希必须输出为 buffer - let signature = nacl.sign.detached(hashBuf, Buffer.from(seckey, 'hex')) + let signature = nacl.sign.detached(hashBuf, Buffer.from(prikey, 'hex')) return Buffer.from(signature).toString('hex') // 签名是64节,128个hex字符 - } else if (tool === 'eccrypto' && seckey.length === 64) { + } else if (tool === 'eccrypto' && prikey.length === 64) { // eccrypto 对同一组data,seckey生成的签名是固定的,观察到hex长度为140或142,是der格式。 - let signature = await eccrypto.sign(Buffer.from(seckey, 'hex'), this.hash_easy(data, { output: 'buf' })) + let signature = await eccrypto.sign(Buffer.from(prikey, 'hex'), this.hash_easy(data, { output: 'buf' })) return signature.toString('hex') - } else if (seckey.length === 64) { + } else if (prikey.length === 64) { // 纯 crypto - let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(seckey), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。 + let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(prikey), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。 let signer = crypto.createSign(hasher) // 注意,不知为何,hasher必须含有'sha'才能完成签名,例如 sha1, sha256, sha512, sha3, RSA-SHA1, id-rsassa-pkcs1-v1_5-with-sha3-224, 其他都会报错。 signer.update(this.hash_easy(data)).end() let signature = signer.sign(seckeyPEM, 'hex') @@ -368,7 +368,7 @@ class TicCrypto { * @static * @param {String} pass * @param {Object} option - * @return {Object} {pubkey, seckey, address,} + * @return {Object} {pubkey, prikey, address,} * @memberof TicCrypto */ static pass_to_keypair ({ pass, hasher = my.HASHER } = {}) { @@ -382,7 +382,7 @@ class TicCrypto { return { hash: hashBuf.toString('hex'), pubkey: Buffer.from(keypair.publicKey).toString('hex'), // 测试过 不能直接keypair.publicKey.toString('hex'),不是buffer类型 - seckey: Buffer.from(keypair.secretKey).toString('hex'), + prikey: Buffer.from(keypair.secretKey).toString('hex'), } } return null @@ -425,7 +425,7 @@ class TicCrypto { * @static * @param {String} secword * @param {Object} option - * @return {Object} {pubkey, seckey,} + * @return {Object} {pubkey, prikey,} * @memberof TicCrypto */ static secword_to_keypair ({ secword, coin, pass, pathRoot, pathIndex, path, tool, hasher = my.HASHER } = {}) { @@ -450,7 +450,7 @@ class TicCrypto { let keypair = nacl.sign.keyPair.fromSeed(hashBuf) // nacl.sign.keyPair.fromSeed 要求32字节的种子,而 this.secword2seed生成的是64字节种子,所以要先做一次sha256 return { pubkey: Buffer.from(keypair.publicKey).toString('hex'), // 测试过 不能直接keypair.publicKey.toString('hex'),不是buffer类型 - seckey: Buffer.from(keypair.secretKey).toString('hex'), // nacl.sign.keyPair.fromSeed 得到的 seckey 是64字节的,不同于比特币/以太坊的32字节密钥。 + prikey: Buffer.from(keypair.secretKey).toString('hex'), // nacl.sign.keyPair.fromSeed 得到的 prikey 是64字节的,不同于比特币/以太坊的32字节密钥。 tool, } } else { @@ -472,7 +472,7 @@ class TicCrypto { } return { path, - seckey: key.privateKey.toString('hex'), // 或者 key.toJSON().privateKey。或者 key.privateKey.slice(2) 删除开头的'0x'如果是ethers.HDNode.fromMnemonic(secword)的结果 + prikey: key.privateKey.toString('hex'), // 或者 key.toJSON().privateKey。或者 key.privateKey.slice(2) 删除开头的'0x'如果是ethers.HDNode.fromMnemonic(secword)的结果 pubkey: key.publicKey.toString('hex'), } } @@ -591,29 +591,29 @@ class TicCrypto { * 从私钥到公钥 * * @static - * @param {*} seckey + * @param {*} prikey * @param {*} [option={}] * @return {*} * @memberof TicCrypto */ - static seckey_to_pubkey ({ seckey, curve, compress } = {}) { - if (this.is_seckey({ seckey }) && seckey.length === 64) { + static seckey_to_pubkey ({ prikey, curve, compress } = {}) { + if (this.is_seckey({ prikey }) && prikey.length === 64) { // 只能用于32字节的私钥(BTC, ETH)。也就是不能用于 TIC 的私钥。 curve = my.CURVE_LIST.includes(curve) ? curve : my.CURVE // 默认为 secp256k1 - // return new crypto.createECDH(curve).setPrivateKey(seckey,'hex').getPublicKey('hex', compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错:TypeError: null is not an object (evaluating 'this.rand.getBytes') + // return new crypto.createECDH(curve).setPrivateKey(prikey,'hex').getPublicKey('hex', compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错:TypeError: null is not an object (evaluating 'this.rand.getBytes') // 从 nodejs 10.0 开始,还有 crypto.ECDH.convertKey 方法,更直接。但可惜,浏览器里不存在 crypto.ECDH。 - return this.buf_to_hex(secp256k1.publicKeyCreate(Buffer.from(seckey, 'hex'), compress !== false)) // 可用于浏览器。缺省输出压缩公钥,compress=false时输出非压缩公钥。 - // 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(seckey)).toString('hex') // 可用于浏览器 + return this.buf_to_hex(secp256k1.publicKeyCreate(Buffer.from(prikey, 'hex'), compress !== false)) // 可用于浏览器。缺省输出压缩公钥,compress=false时输出非压缩公钥。 + // 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(prikey)).toString('hex') // 可用于浏览器 // 或者 const ecc = require('eccrypto') // if (compress===false){ - // return ecc.getPublic(this.hex_to_buf(seckey)).toString('hex') + // return ecc.getPublic(this.hex_to_buf(prikey)).toString('hex') // }else{ - // return ecc.getPublicCompressed(this.hex_to_buf(seckey)).toString('hex') + // return ecc.getPublicCompressed(this.hex_to_buf(prikey)).toString('hex') // } - // 注意,Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(seckey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同 - } else if (this.is_seckey({ seckey }) && seckey.length === 128) { + // 注意,Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(prikey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同 + } else if (this.is_seckey({ prikey }) && prikey.length === 128) { // 用于64字节=128 hex的 TIC 私钥 - let keypair = nacl.sign.keyPair.fromSecretKey(Buffer.from(seckey, 'hex')) + let keypair = nacl.sign.keyPair.fromSecretKey(Buffer.from(prikey, 'hex')) return Buffer.from(keypair.publicKey).toString('hex') // 测试过 不能直接keypair.publicKey.toString('hex'),不是buffer类型 } return null @@ -623,21 +623,21 @@ class TicCrypto { * 从私钥到地址 * * @static - * @param {*} seckey + * @param {*} prikey * @param {*} option * @return {*} * @memberof TicCrypto */ - static seckey_to_address ({ seckey, coin, world } = {}) { + static seckey_to_address ({ prikey, coin, world } = {}) { coin = coin?.toUpperCase() || my.COIN - if (this.is_seckey({ seckey })) { + if (this.is_seckey({ prikey })) { /** @type {*} */ let pubkey if (coin === 'ETH') { - pubkey = this.seckey_to_pubkey({ seckey, compress: false }) + pubkey = this.seckey_to_pubkey({ prikey, compress: false }) return this.pubkey_to_address({ pubkey: pubkey, coin, world }) } else { - pubkey = this.seckey_to_pubkey({ seckey, compress: true }) + pubkey = this.seckey_to_pubkey({ prikey, compress: true }) return this.pubkey_to_address({ pubkey: pubkey, coin, world }) } } @@ -912,14 +912,14 @@ class TicCrypto { kp = nacl.sign.keyPair() } return { - seckey: Buffer.from(kp.secretKey).toString('hex'), + prikey: Buffer.from(kp.secretKey).toString('hex'), pubkey: Buffer.from(kp.publicKey).toString('hex'), } } else { - let seckey = this.randomize_seckey() - let pubkey = this.seckey_to_pubkey({ seckey }) + let prikey = this.randomize_seckey() + let pubkey = this.seckey_to_pubkey({ prikey }) return { - seckey, + prikey, pubkey, } }