我有一个用node.js编写的服务器,我想从C#应用程序接收加密的消息。我尝试为此任务首先实现RSA
,但无济于事,因为在C#应用使用服务器生成的密钥对消息进行加密之后,我无法解密消息。
我尝试使用node-rsa npm在服务器端生成密钥,并在尝试解密消息时出现此错误
“解密期间出错(可能是错误的密钥)。原始错误: 错误:数据或密钥不正确”。
我也尝试过使用加密模块进行解密,但是却收到此错误
“错误:0406506C:rsa例程:rsa_ossl_private_decrypt:数据更大 比mod len”。
C#应用程序是一个控制台应用程序,因为它仅用于测试加密,它使用RSAServiceProvider
导入服务器生成的密钥(以pem格式存储),对消息进行加密(或密钥(如果我也要实现AES
),然后通过将其写入文件将其发送回服务器。
这是rsa-wrapper.js
文件,其中包含rsa
实现:
const NodeRSA = require('node-rsa');
const fs = require('fs');
var key;
var generate = function () {
key = new NodeRSA();
key.generateKeyPair(2048, 65537);
fs.writeFileSync('./keys/public-key.pem', key.exportKey('pkcs8-public-pem'));
};
var encrypt = function (message) {
let encrypted = key.encrypt(message, 'base64');
return encrypted;
};
var decrypt = function (cipherText) {
let decrypted = key.decrypt(cipherText, 'utf8');
return decrypted;
}
module.exports.generate = generate;
module.exports.test = test;
module.exports.encrypt = encrypt;
module.exports.decrypt = decrypt;
这是app.js文件,其中仅包含用于测试加密的GET函数:
const express = require('express');
const rsaWrapper = require('./components/rsa-wrapper.js');
const app = express();
const fs = require('fs');
app.listen(3000);
app.get('/', function(req, res) {
console.log('Working');
res.render('index.ejs');
});
app.get('/generate', function(req, res) {
rsaWrapper.generate();
console.log('The keys have been generated successfully.');
res.render('index.ejs');
});
app.get('/decrypt', function(req, res) {
fs.readFile('./cipher-text.txt', (err, data) => {
if (err) throw err;
console.log('The original message is:' + rsaWrapper.decrypt(data));
});
res.render('index.ejs');
});
这是用C#编写的控制台应用程序,用于使用服务器生成的公共密钥对消息进行加密:
static void Main(string[] args) {
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters rsaParam = rsa.ExportParameters(false);
String publicKey = File.ReadAllText(@"D:\NodeProjects\Test project\keys\public-key.pem").Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
publicKey = publicKey.Replace("\n", String.Empty);
publicKey = publicKey.Replace("\r", String.Empty);
publicKey = publicKey.Replace("\t", String.Empty);
rsaParam.Modulus = Convert.FromBase64String(publicKey);
byte[] intBytes = BitConverter.GetBytes(65537);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
rsaParam.Exponent = intBytes;
rsa.ImportParameters(rsaParam);
string msg = ".";
byte[] encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(msg), true);
string cipherText = Convert.ToBase64String(encrypted);
File.WriteAllText(@"D:\NodeProjects\Test project\cipher-text.txt", cipherText);
Console.WriteLine(publicKey);
Console.WriteLine(cipherText);
Console.ReadLine();
}
这是我尝试使用的第二个rsa-wrapper.js,但也导致失败:
const rsaWrapper = {};
const fs = require('fs');
const NodeRSA = require('node-rsa');
const crypto = require('crypto');
// load keys from file
rsaWrapper.initLoadServerKeys = () => {
rsaWrapper.serverPub = fs.readFileSync('./keys/public-key.pem');
rsaWrapper.serverPrivate = fs.readFileSync('./keys/private-key.pem');
};
rsaWrapper.generate = () => {
let key = new NodeRSA();
key.generateKeyPair(2048, 65537);
fs.writeFileSync('./keys/private-key.pem', key.exportKey('pkcs8-private-pem'));
fs.writeFileSync('./keys/public-key.pem', key.exportKey('pkcs8-public-pem'));
return true;
};
rsaWrapper.serverExampleEncrypt = () => {
console.log('Server public encrypting');
let enc = rsaWrapper.encrypt(rsaWrapper.serverPub, 'Server init hello');
console.log('Encrypted RSA string ', '\n', enc);
let dec = rsaWrapper.decrypt(rsaWrapper.serverPrivate, enc);
console.log('Decrypted RSA string ...');
console.log(dec);
};
rsaWrapper.encrypt = (publicKey, message) => {
let enc = crypto.publicEncrypt({
key: publicKey,
padding: crypto.RSA_PKCS1_OAEP_PADDING
}, Buffer.from(message));
return enc.toString('base64');
};
rsaWrapper.decrypt = (privateKey, message) => {
let enc = crypto.privateDecrypt({
key: privateKey,
padding: crypto.RSA_PKCS1_OAEP_PADDING
}, Buffer.from(message, 'base64'));
return enc.toString();
};
module.exports = rsaWrapper;