coc*_*h54 3 javascript encryption rsa node.js cryptojs
我正在使用带有nodejs加密模块的RSA加密。
我想使用PRIVATE KEY加密消息并使用PUBLIC KEY解密。使用填充方案(例如使用公钥加密)对同一条消息也总是会产生不同的结果。
所以我使用了如下的基本加密模块
var crypto = require('crypto');
var fs = require('fs');
const path = require('path');
var PRIVKEY = fs.readFileSync(path.join(__dirname, 'private.key'), 'utf8');
var PUBKEY = fs.readFileSync(path.join(__dirname, 'pub.key'), 'utf8');
// RSA PRIVATE ENCRYPT -> PUBLIC DECRYPT //
myMSG = "apple";
console.log('myMSG SIZE:', myMSG.length);
function privENC_pubDEC(originMSG){
encmsg = crypto.privateEncrypt(PRIVKEY, Buffer.from(originMSG, 'utf8') ).toString('base64');
msg = crypto.publicDecrypt(PUBKEY, Buffer.from(encmsg, 'base64'));
console.log("Encrypted with private key : "+encmsg);
console.log(msg.toString());
}
// RSA PUBLIC ENCRYPT -> PRVATE DECRYPT //
function pubENC_privDEC(originMSG){
encmsg = crypto.publicEncrypt({key:PUBKEY, padding:crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(originMSG, 'utf8') ).toString('base64');
msg = crypto.privateDecrypt({key:PRIVKEY, padding:crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(encmsg, 'base64'));
console.log("\nEncrypted with public key : "+encmsg);
console.log(msg.toString());
}
privENC_pubDEC(myMSG);
pubENC_privDEC(myMSG);
Run Code Online (Sandbox Code Playgroud)
结果
C:\Users\LSW>node crypto.js
myMSG SIZE: 5
Encrypted with private key : fbUZwj+UZP92HQYRc+EJTqSztJTY/Sit5axPZ0NVBuDAC8ZwvvC96pxxDGpra4Yg8MjcXyjvnT8rrrgHu0T0wA==
apple
Encrypted with public key : ze+5TdWtR8hkpNPIVa5HSasOxs3Pr8FA/1/zUGqDUQmIhs/miWt5pgU9kIAiryKfgGa0+p9RfHPMwZ1VMSA7Bw==
apple
C:\Users\LSW>node crypto.js
myMSG SIZE: 5
Encrypted with private key : fbUZwj+UZP92HQYRc+EJTqSztJTY/Sit5axPZ0NVBuDAC8ZwvvC96pxxDGpra4Yg8MjcXyjvnT8rrrgHu0T0wA==
apple
Encrypted with public key : OdEpjloUDWI8+YjWkE5cmBC/fJL2QnRLKBXfjaP5h5qyB1OMcm9JGGNSTiAAL2u8O5jjdQAavB9Rn+cdRDjLyA==
apple
C:\Users\LSW>node crypto.js
myMSG SIZE: 5
Encrypted with private key : fbUZwj+UZP92HQYRc+EJTqSztJTY/Sit5axPZ0NVBuDAC8ZwvvC96pxxDGpra4Yg8MjcXyjvnT8rrrgHu0T0wA==
apple
Encrypted with public key : INspxkyFu2AWGVYwSvOGOPH1fhE3qVVxiqz+SmyHU8wTDNKHj4gVVHqO+8AZOJvi4NfyekI2MMwpFDU4mUjEXA==
apple
Run Code Online (Sandbox Code Playgroud)
我期望公共加密-> PRVATE DECRYPT运行良好。由于填充方案,它总是返回不同的结果。
但是,尽管使用了填充方案,但是PRIVATE ENCRYPT-> PUBLIC DECRYPT总是返回相同的消息。
有什么解决方案可以使它与Nodejs加密模块产生不同的消息吗?
这是根据填补方案为RSA签名和加密预期行为如由OpenSSL的,实现其crypto利用。
我不知道你要使用的功能是什么privateEncrypt(),并publicDecrypt()为。如果您打算对数据进行签名,请在下面查看我的更新。无论如何,对于这些功能,crypto文档解释为仅RSA_PKCS1_PADDING在引擎盖下公开哪些OpenSSL映射到确定性RSASSA-PKCS1-v1_5填充方案。这意味着对于相同的键和相同的数据,结果数据将相同。
要进行加密和解密,请使用publicEncrypt()和privateDecrypt()选择RSA_PKCS1_PADDING模式。这将转换为RSAES-PKCS1-v1_5,该方案包含随机元素,这些元素会导致您在重复运行中观察到不同的输出。根据文档,默认情况下crypto使用RSA_PKCS1_OAEP_PADDING填充。这代表了非确定性的最优非对称加密填充。
有关PKCS#1定义的方案的摘要,请参见PKCS#1方案。
更新:您可能要使用和Sign class而不是privateEncrypt()和publicDecrypt()函数。它的sign()函数确实支持概率填充模式,OpenSSL通过RSASSA-PSS支持该概率填充模式。以您的示例代码为起点,它看起来像这样:
const sign = crypto.createSign('SHA256')
sign.update(Buffer.from(originMSG, 'utf8'))
signature = sign.sign({key:PRIVKEY, padding:crypto.constants.RSA_PKCS1_PSS_PADDING}).toString('base64')
Run Code Online (Sandbox Code Playgroud)
每次签名都会不同。请注意,您不能对其进行“解密”,这是单向操作。您只能使用带有Verify类的公钥来验证它:
const verify = crypto.createVerify('SHA256')
verify.update(Buffer.from(originMSG, 'utf8'))
verifyRes = verify.verify({key:PUBKEY, padding:crypto.constants.RSA_PKCS1_PSS_PADDING}, Buffer.from(signature, 'base64'))
Run Code Online (Sandbox Code Playgroud)