我需要使用公钥(pem文件)加密字符串,然后使用私钥(也是pem)对其进行签名。
我正在加载pem文件:
publicCert = fs.readFileSync(publicCertFile).toString();
但是经过几个小时的淘汰谷歌我似乎找不到使用公钥加密数据的方法。在php中我只是调用openssl_public_encrypt,但我没有在节点或任何模块中看到任何相应的函数。
如果有人有任何建议,请告诉我。
答案 0 :(得分:104)
没有图书馆必要的朋友,
输入crypto
这是一个可用于使用RSA密钥加密/解密字符串的简洁小模块:
var crypto = require("crypto");
var path = require("path");
var fs = require("fs");
var encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey) {
var absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey);
var publicKey = fs.readFileSync(absolutePath, "utf8");
var buffer = Buffer.from(toEncrypt);
var encrypted = crypto.publicEncrypt(publicKey, buffer);
return encrypted.toString("base64");
};
var decryptStringWithRsaPrivateKey = function(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
var absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey);
var privateKey = fs.readFileSync(absolutePath, "utf8");
var buffer = Buffer.from(toDecrypt, "base64");
var decrypted = crypto.privateDecrypt(privateKey, buffer);
return decrypted.toString("utf8");
};
module.exports = {
encryptStringWithRsaPublicKey: encryptStringWithRsaPublicKey,
decryptStringWithRsaPrivateKey: decryptStringWithRsaPrivateKey
}
我建议不要在可能的情况下使用同步fs方法,你可以使用Promises来改善它,但对于简单的用例,这是我看过的工作方法,并且会采用
答案 1 :(得分:8)
更新的公共/私有解密和加密模块是URSA。 node-rsa模块已过时。
这个Node模块提供了一套相当完整的包装器 OpenSSL的RSA公钥/私钥加密功能。
npm install ursa
答案 2 :(得分:7)
答案 3 :(得分:4)
TL; DR:Ursa是你最好的选择。它真的很时髦,这不是节点加密的标准。
我发现的其他解决方案要么在Windows中不起作用,要么实际上不是加密库。路易推荐的Ursa看起来是最好的选择。如果你不关心窗户,你会更加金色。关于Ursa的注意事项,我必须安装Open SSL以及名为“Visual C ++ 2008 Redistributables”的东西才能使npm安装正常工作。在这里获取垃圾:http://slproweb.com/products/Win32OpenSSL.html
细分:
这就是我能找到的所有内容。
答案 4 :(得分:4)
我在节点10上对此进行了测试,您可以使用加密/解密功能(对Jacob的答案有小的改动)
const crypto = require('crypto')
const path = require('path')
const fs = require('fs')
function encrypt(toEncrypt, relativeOrAbsolutePathToPublicKey) {
const absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey)
const publicKey = fs.readFileSync(absolutePath, 'utf8')
const buffer = Buffer.from(toEncrypt, 'utf8')
const encrypted = crypto.publicEncrypt(publicKey, buffer)
return encrypted.toString('base64')
}
function decrypt(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
const absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey)
const privateKey = fs.readFileSync(absolutePath, 'utf8')
const buffer = Buffer.from(toDecrypt, 'base64')
const decrypted = crypto.privateDecrypt(
{
key: privateKey.toString(),
passphrase: '',
},
buffer,
)
return decrypted.toString('utf8')
}
const enc = encrypt('hello', `public.pem`)
console.log('enc', enc)
const dec = decrypt(enc, `private.pem`)
console.log('dec', dec)
对于密钥,您可以使用
const { writeFileSync } = require('fs')
const { generateKeyPairSync } = require('crypto')
function generateKeys() {
const { privateKey, publicKey } = generateKeyPairSync('rsa', {
modulusLength: 4096,
publicKeyEncoding: {
type: 'pkcs1',
format: 'pem',
},
privateKeyEncoding: {
type: 'pkcs1',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase: '',
},
})
writeFileSync('private.pem', privateKey)
writeFileSync('public.pem', publicKey)
}
答案 5 :(得分:2)
节点版本v0.11.13或更低版本本身不支持此功能,但似乎下一版本的节点(a.k.a v0.12)将支持此功能。
以下是线索:https://github.com/joyent/node/blob/v0.12/lib/crypto.js#L358
请参阅crypto.publicEncrypt
和crypto.privateDecrypt