如何在Node.JS中加载加密私钥
How to load encrypted private key in Node.JS
我想使用带有加密私钥的节点Crypto:Sign模块。加密模块中是否有允许我解密私钥的功能?
例如,在Python中有一个OpenSSL.crypto.load_privatekey函数,它使用一个密码短语来解密私钥。我希望实现相同的功能,但使用Node.JS库。
const crypto = require('crypto');
const sign = crypto.createSign('sha256');
sign.update('some data to sign');
let private_key = '-----BEGIN ENCRYPTED PRIVATE KEY-----'n' +
'ABCDEFGHIJKLMNOP'n' +
'-----END ENCRYPTED PRIVATE KEY-----'n';
// Somehow decrypt private_key using passphrase.
what_to_do(????);
console.log(sign.sign(private_key).toString('hex'));
我意识到这个问题现在已经是旧的AF了,但我在自己解决问题时遇到了这个问题,最终找到了答案,所以我将与后人分享:
我正在开发一个应用程序,即使在没有HTTPS连接的情况下也试图保护它。我正在使用非对称加密处理登录。用户提供他们的用户名,这会导致在后端进行查找,检索用户在注册时计算的公钥。然后,公钥用于使用JSEncrypt加密客户端上的密码,然后将其发送回后端,用私钥进行解密和验证,私钥也会在注册时以加密形式进行计算和存储。
诀窍是,由于加密的私钥存储为纯文本,因此必须将其重新加载到KeyObject
中,然后才能被加密方法使用。我的密钥创建如下:
CRYPTO.generateKeyPair('rsa', {
'modulusLength': 4096,
'publicKeyEncoding': {
'type': 'spki',
'format': 'pem',
},
'privateKeyEncoding': {
'type': 'pkcs8',
'format': 'pem',
'cipher': 'aes-256-cbc',
'passphrase': 'passphrase'
}
}, (err, publicKey, privateKey) => { /* store keys, return public key */ }
根据文档,如果提供了编码选项,函数的行为就好像对结果调用了KeyObject.export()
一样,因此在回调中得到的是字符串而不是KeyObject
。无论如何,这是将密钥存储在数据库中所必需的,正如我正在做的,并且我认为OP正在做的那样,因为他正试图从字符串加载密钥。
所以现在我们必须把它改回来。这是用CRYPTO.createPrivateKey()
完成的。我的函数调用如下:
var privateKey = CRYPTO.createPrivateKey({
'key': encodedPrivateKeyString,
'format': 'pem',
'type': 'pkcs8',
'cipher': 'aes-256-cbc',
'passphrase': 'passphrase'
});
它镜像私钥的初始创建,并产生可用于CRYPTO.privateDecrypt()
或CRYPTO.Sign.sign()
的KeyObject
。
事实上,我在生成用于令牌验证的密钥后立即使用sign,并能够使其与以下内容一起工作:
var signToken = CRYPTO.createSign('SHA256');
signToken.write('random text to sign');
signToken.end();
var token = signToken.sign({ 'key': privateKey, 'passphrase': 'passphrase' }, 'hex');
但在这一点上,我在CRYPTO.generateKeyPair()
回调中,所以原始变量仍然可用,无论它们的确切类型是什么。我假设在这一步上,privateKey
实际上不是一个字符串,尽管我可以像它一样将其存储到数据库中,而是一个KeyObject
,或者它不知何故知道或默认了我没有提供的参数选项。然而,当我在登录时回到后台验证用户密码时,我必须从纯文本中再次创建私钥,所以当我调用CRYPTO.privateDecrypt()
时,我不得不如上所述首先重新创建私钥KeyObject
,然后像这样调用CRYPTO.privateDecrypt()
:
var hash = CRYPTO.privateDecrypt({
'key': privateKey,
'passphrase': 'passphrase',
'cipher': 'aes-256-cbc',
'padding': CRYPTO.constants.RSA_PKCS1_PADDING
}, buffer).toString();
然后可以将该字符串与注册时存储的哈希进行比较,以对用户进行身份验证。如果你所做的只是签名,你可能不会像我那样提供额外的参数,但如果你从字符串中重新创建私钥,你可能需要提供更多。或者,您可以像我一样,将编码的私钥作为字符串提供您的密码短语,并且大多数解释都是不必要的,因为它涉及解密而不是签名。
不管怎样,我都记录了我的挣扎。希望这能帮助到别人。
- 如何使用url加载程序在webpack中导入多个图像
- 如何在生成下载文件时显示加载动画
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 无法在通过jQuery的ajax加载的页面中执行javascript
- Emberjs应用程序加载在除Index之外的所有路由上
- 在chrome.tabs.onCreated之后加载HTML页面
- 单击F5时如何停止页面加载
- HTML5音频加载和播放获胜'我不能在iPad上工作
- 跟踪在页面加载时应用内联样式的JavaScript
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- jQuery Lazy加载动画滚动
- Html页面上的多个Base64图像和平滑加载
- 如何创建带有插槽的vue js组件预加载程序
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- 如何使该数据在所有元素中加载
- 如何在Node.JS中加载加密私钥
- 加载在JSBN中创建的RSA公钥,然后加密消息
- 如何加载 PEM 格式的公钥以进行加密
- Javascript加密哈希保护加载器
- 我可以加密内容吗;t出现在视图源中,然后显示在页面加载中