From 00287a0944af8c6011d7f6261d3dfe59e553588b Mon Sep 17 00:00:00 2001 From: "luk.lu" Date: Fri, 7 May 2021 16:29:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=8A=20eccrypto=20=E6=8D=A2=E6=88=90=20ecc?= =?UTF-8?q?rypto-js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.xlsx | Bin 18374 -> 19201 bytes index.js | 86 +++++++++++++++++++++++++++++---------------------- package.json | 2 +- 3 files changed, 50 insertions(+), 38 deletions(-) diff --git a/README.xlsx b/README.xlsx index 9cacbee7a5f48ef14f4e7f55d196329755c8753f..86752c8787c122124e32f983513f3748e7a96ca9 100644 GIT binary patch delta 15797 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 delta 14991 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 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 ciph = crypto.createCipher(my.CIPHER_LIST.indexOf(cipher) >= 0 ? cipher : my.CIPHER, this.hash(key)) + const iv = crypto.randomBytes(16) + let ciph = crypto.createCipheriv(my.CIPHER_LIST.indexOf(cipher) >= 0 ? cipher : my.CIPHER, this.hex2buf(this.hash(key)), iv) if (typeof data !== 'string' && !(data instanceof Buffer) && !(data instanceof DataView)) data = JSON.stringify(data) - let encrypted = ciph.update(data, inputEncoding, outputEncoding) - encrypted += ciph.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string - return encrypted + let ciphertext = ciph.update(data, inputEncoding, outputEncoding) + ciphertext += ciph.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string + return { iv: iv.toString('hex'), ciphertext } } - } else if (tool === 'eccrypto') { - // data 应当是 utf8 的字符串。// 但在浏览器里不能使用 Failed to execute 'encrypt' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView)' - let cipherobject = await eccrypto.encrypt(this.hex2buf(key), data) - return cipherobject } else if (keytype === 'seckey') { + // 尚未走通,不能使用 ticCrypto 生成的 Elliptic curve 椭圆曲线算法公私钥,只能用 crypto.generateKeypairs() 生成的 rsa 公私钥 let seckeyPEM = await new keyman.Key('oct', this.hex2buf(key), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。 - return crypto.privateEncrypt(seckeyPEM, Buffer.from(data)) + return crypto.privateEncrypt(seckeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果都一样。 } else if (keytype === 'pubkey') { - let pubkeyPEM = await new keyman.Key('oct', this.hex2buf(key), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。 - return crypto.publicEncrypt(pubkeyPEM, Buffer.from(data)) + let pubkeyPEM = await new keyman.Key('oct', this.hex2buf(key), { namedCurve: 'P-256K' }).export('pem') + return crypto.publicEncrypt(pubkeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果不一样。 } return null } @@ -210,34 +215,39 @@ class TICrypto { * @return {String} * @memberof TICrypto */ - static async decrypt(data, { keytype, key, input, output, cipher, format } = {}) { + static async decrypt(data = {}, { keytype = 'pwd', key, input, output, cipher } = {}) { // data 应当是 encrypt 输出的数据类型 - if (keytype === 'pwd') { - if (data && (typeof data === 'string' || data instanceof Buffer) && typeof key === 'string') { - let inputEncoding = my.OUTPUT_LIST.indexOf(input) >= 0 ? input : my.OUTPUT // input (=output of encrypt) could be 'latin1', 'base64', 'hex' by default for string or ignored for Buffer - let outputEncoding = output === 'buf' ? undefined : my.INPUT_LIST.indexOf(output) >= 0 ? output : my.INPUT // output (=input of encrypt) could be 'latin1', 'ascii', 'utf8' by default or 'buf' to Buffer explicitly - let decipher = crypto.createDecipher(my.CIPHER_LIST.indexOf(cipher) >= 0 ? cipher : my.CIPHER, this.hash(key)) - let decrypted = decipher.update(data, inputEncoding, outputEncoding) - decrypted += decipher.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string - if (format === 'json') { - // 如果用户输入错误密码,deciper也能返回结果。为了判断是否正确结果,对应当是 json 格式的原文做解析来验证。 - try { - JSON.parse(decrypted) - } catch (exception) { - return null - } - } - return decrypted - } - } else if (keytype === 'seckey') { - // cipherobject 需要是 eccrypto 自身encrypt方法返回的对象 + if (tool === 'eccrypto') { try { - let plaindata = await eccrypto.decrypt(Buffer.from(key, 'hex'), data) // eccrypto 需要调用 Buffer.compare 方法,不能在这里直接用 hex2buf + // eccrypto 只能接受 Buffer, 不接受 Uint8Array, 因为 eccrypto 需要调用 Buffer.compare 方法,不能在这里直接用 hex2buf + // eccrypto 也只能接受 Buffer, 不接受 Uint8Array + let plaindata = await eccrypto.decrypt(Buffer.from(key, 'hex'), data) // data 需要是 eccrypto 自身encrypt方法返回的 cipherobject return plaindata.toString('utf8') } catch (exception) { // eccrypto 对无法解密的,会抛出异常 return null } + } else if (keytype === 'pwd') { + if ((typeof data.ciphertext === 'string' || data.ciphertext instanceof Buffer) && typeof key === 'string') { + let inputEncoding = my.OUTPUT_LIST.indexOf(input) >= 0 ? input : my.OUTPUT // input (=output of encrypt) could be 'latin1', 'base64', 'hex' by default for string or ignored for Buffer + let outputEncoding = output === 'buf' ? undefined : my.INPUT_LIST.indexOf(output) >= 0 ? output : my.INPUT // output (=input of encrypt) could be 'latin1', 'ascii', 'utf8' by default or 'buf' to Buffer explicitly + let decipher = crypto.createDecipheriv( + my.CIPHER_LIST.indexOf(cipher) >= 0 ? cipher : my.CIPHER, + this.hex2buf(this.hash(key)), + Buffer.from(data.iv, 'hex') + ) + let decrypted = decipher.update(data.ciphertext, inputEncoding, outputEncoding) + decrypted += decipher.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string + // 如果用户输入错误密码,deciper也能解密,无法自动判断是否正确结果。可在返回后人工判断。 + return decrypted + } + } else if (keytype === 'seckey') { + // 尚未走通,不能使用 ticCrypto 生成的 Elliptic curve 椭圆曲线算法公私钥 + let seckeyPEM = await new keyman.Key('oct', this.hex2buf(key), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。 + return crypto.privateDecrypt(seckeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果都一样。 + } else if (keytype === 'pubkey') { + let pubkeyPEM = await new keyman.Key('oct', this.hex2buf(key), { namedCurve: 'P-256K' }).export('pem') + return crypto.publicDecrypt(pubkeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果不一样。 } return null } @@ -957,12 +967,14 @@ class TICrypto { } /** - * + * 生成 uuid * * @static * @memberof TICrypto */ - static randomUuid = uuid.v4 + static randomUuid() { + return uuid.v4() + } /** * 获取梅克哈希 diff --git a/package.json b/package.json index 0366b00..aa38aed 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "big-integer": "^1.6.48", "bip39": "^3.0.2", "bs58check": "^2.1.2", - "eccrypto": "^1.1.3", + "eccrypto-js": "^5.4.0", "hdkey": "^1.1.1", "js-crypto-key-utils": "^0.7.3", "keccak": "^2.1.0",