Node.js 和 webcrypto 之间的 RSA 加密

Posted

技术标签:

【中文标题】Node.js 和 webcrypto 之间的 RSA 加密【英文标题】:RSA crypto between Node.js and webcrypto 【发布时间】:2015-11-04 21:11:34 【问题描述】:

我真的被困在这上面了!我正在尝试做的事情:

使用 ursa/webcrypto 生成 RSA 密钥对 通过网络以 PEM 形式发送公钥 在另一端导入公钥,并用它加密一些文本 发回密文并在另一端使用私钥解密

现在,如果我尝试使用 ursa 进行加密部分,我会以某种方式在浏览器中收到未定义的 DOMException,或者当我在浏览器中进行加密时,我会在 Node.js 中收到此错误:

Missing error handler on `socket`.
Error: error:040A1079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error
    at Error (native)
    at Object.decrypt (/home/jeroen/projects/crypto-nodebrowser/node_modules/ursa/lib/ursa.js:358:33)
    at Socket.<anonymous> (/home/jeroen/projects/crypto-nodebrowser/server.js:34:50)
    at emitOne (events.js:77:13)
    at Socket.emit (events.js:169:7)
    at Socket.onevent (/home/jeroen/projects/crypto-nodebrowser/node_modules/socket.io/lib/socket.js:330:8)
    at Socket.onpacket (/home/jeroen/projects/crypto-nodebrowser/node_modules/socket.io/lib/socket.js:290:12)
    at Client.ondecoded (/home/jeroen/projects/crypto-nodebrowser/node_modules/socket.io/lib/client.js:193:14)
    at Decoder.Emitter.emit (/home/jeroen/projects/crypto-nodebrowser/node_modules/component-emitter/index.js:134:20)
    at Decoder.add (/home/jeroen/projects/crypto-nodebrowser/node_modules/socket.io-parser/index.js:247:12)

我在https://github.com/jvanveen/crypto-nodebrowser 做了一个显示问题的最小代码示例。欢迎对此提供任何帮助!

【问题讨论】:

【参考方案1】:

你能告诉我们你正在运行的代码和运行它的浏览器吗?

某些浏览器可能仅使用 SHA-1 执行 RSA-OAEP,但从您给出的简要描述来看,它在解密时存在问题。我认为需要更多细节。

【讨论】:

嗨,我正在使用最新的 Chromium 版本进行测试。当我运行服务器并打开页面时,会执行一些有点骇人听闻的测试用例。此时第一个测试用例通过:它能够在 node.js 上生成密钥对,将其转换为 jwk,将 jwk 发送到浏览器,webcrypto 能够导入 jwk 并导出 jwk,jwk 被发送回服务器和服务器确认jwk/pem还是一样的。第二个测试用例失败。它首先测试密钥是否可用于本地加密/解密,然后将密文发送到服务器。在服务器上我收到 oaep 错误... NodeRSA 和 Ursa 都在 OAEP 填充方面产生了类似的错误:Error: error:040A1079:rsaroutines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep 解码错误 从 ursa/nodersa 导入的 webcrypto 密钥的模数长度与生成的密钥稍有不同:keypair.private.algorithm.modulusLength => 2047 keypair.generated.privateKey.algorithm.modulusLength => 2048 密钥对。 generated.privateKey.algorithm.publicExponent => [1, 0, 1] keypair.private.algorithm.publicExponent => [1, 0, 1] 有人建议 Node.js 默认使用 sha1 而不是 sha256 哈希。我不确定这是否导致了这里的问题...... 刚刚通过将 webcrypto 设置为 sha1 确认了这一点!想知道我是否可以将 Node.js 端更改为使用 sha256。【参考方案2】:

好的,我终于明白了。 Openssl 具有使用 SHA1 硬编码的 OAEP 填充,因此如果您想使用 RSA-OAEP-256,则 ursa 的 openssl 绑定不适合。我找不到使用 node-rsa 进行这项工作的方法,但是 Node-forge 在这里非常简单。只需使用类似的东西:

var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', 
    md: forge.md.sha256.create()
);

【讨论】:

以上是关于Node.js 和 webcrypto 之间的 RSA 加密的主要内容,如果未能解决你的问题,请参考以下文章

Node.js中的模块机制

使用 webpack 重用全栈模块

Node.js 中的模块和包之间的区别?

Nodejs AES-256-GCM 在客户端通过浏览器 webcrypto api 加密和解密

node.js 和 PHP 之间如何通信?

在 Node.js 和 Vue.js 之间共享 TypeScript 代码