diff --git a/index.js b/index.js index 1e02765..03ccdc3 100644 --- a/index.js +++ b/index.js @@ -155,20 +155,20 @@ module.exports = { , async sign(data, seckey, option={}) { // data can be string or buffer or object, results are the same if (this.isHashable(data) && this.isSeckey(seckey) && seckey.length===64) { - if (option.tool==='crypto') { // 纯 crypto + if (option.tool==='nacl') { + // 这样不行,无法和verify共享一套公私钥。 + // let naclSeckey = this.buf2hex(nacl.sign.keyPair.fromSeed(seckey).seckey) + // return await this.sign(data, naclSeckey, option) + }else if (option.tool==='eccrypto') { // eccrypto 对同一组data,seckey生成的签名是固定的,观察到hex长度为140或142,是der格式。 + let signature = await eccrypto.sign(Buffer.from(seckey,'hex'), this.hash(data, {output:'buf'})) + return signature.toString('hex') + }else { // 纯 crypto let seckeyPEM = await new keyman.Key('oct', this.hex2buf(seckey), {namedCurve:'P-256K'}).export('pem') // 私钥导出的der格式为144字节。 let hasher=my.HASHER_LIST.indexOf(option.hasher)>=0?option.hasher:my.HASHER let signer=crypto.createSign(hasher) signer.update(this.hash(data, option)).end() let signature = signer.sign(seckeyPEM, 'hex') return signature // 发现同样的输入,nodejs里每次调用会生成不同的 signature, 且长度不定(140,142,144 hex) 但都可以通过 verify。但在浏览器里调用,signature却是固定的。 - }else if (option.tool==='nacl') { - // 这样不行,无法和verify共享一套公私钥。 - // let naclSeckey = this.buf2hex(nacl.sign.keyPair.fromSeed(seckey).seckey) - // return await this.sign(data, naclSeckey, option) - }else { // default to eccrypto,因为它对同一组data,seckey生成的签名是固定的,观察到hex长度为140或142,是der格式。 - let signature = await eccrypto.sign(Buffer.from(seckey,'hex'), this.hash(data, {output:'buf'})) - return signature.toString('hex') } } if (this.isHashable(data) && this.isSeckey(seckey) && seckey.length===128) { // 使用nacl的签名算法。注意,nacl.sign需要的seckey是64字节=128字符。 @@ -182,23 +182,23 @@ module.exports = { , async verify (data, signature, pubkey, option={}) { // data could be anything, but converts to string or remains be Buffer/TypedArray/DataView if (this.isHashable(data) && this.isSignature(signature) && this.isPubkey(pubkey) && signature.length>=140){ - if (option.tool==='crypto') { // 纯 crypto - let pubkeyPEM = await new keyman.Key('oct', this.hex2buf(pubkey), {namedCurve:'P-256K'}).export('pem') // 公钥导出的der格式为88字节。经测试,同一对压缩和非压缩公钥得出的结果一模一样。 - let hasher=my.HASHER_LIST.indexOf(option.hasher)>=0?option.hasher:my.HASHER - let verifier = crypto.createVerify(hasher) - verifier.update(this.hash(data, option)).end() // end() 在 nodejs 12 里返回verifier自身,但在浏览器里返回 undefined,因此不能串联运行。 - let verified = verifier.verify(pubkeyPEM, signature, 'hex') // 如果给signature添加1位hex,crypto 的 verify结果也是true! 估计因为一位hex不被转成字节。 - return verified - }else if ('nacl'===option.tool) { + if ('nacl' === option.tool) { // 这样不行,无法和sign共享一套公私钥 // let naclPubkey = nacl.sign.keyPair.fromSeed() - }else { // 默认使用 eccrypto + }else if ('eccrypto' === option.tool) { // 默认使用 eccrypto 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){ // 对能够验证的,eccrypto返回 null;对无法验证的,抛出异常 return false } + }else { // 纯 crypto + let pubkeyPEM = await new keyman.Key('oct', this.hex2buf(pubkey), {namedCurve:'P-256K'}).export('pem') // 公钥导出的der格式为88字节。经测试,同一对压缩和非压缩公钥得出的结果一模一样。 + let hasher=my.HASHER_LIST.indexOf(option.hasher)>=0?option.hasher:my.HASHER + let verifier = crypto.createVerify(hasher) + verifier.update(this.hash(data, option)).end() // end() 在 nodejs 12 里返回verifier自身,但在浏览器里返回 undefined,因此不能串联运行。 + let verified = verifier.verify(pubkeyPEM, signature, 'hex') // 如果给signature添加1位hex,crypto 的 verify结果也是true! 估计因为一位hex不被转成字节。 + return verified } return false }