Javascript Node.js服务器到服务器加密

Javascript Node.js服务器到服务器加密,javascript,node.js,security,encryption,server-to-server,Javascript,Node.js,Security,Encryption,Server To Server,我想创建一个Node.js守护进程,它运行在多台计算机上,并且能够在不同的守护进程之间交换消息。当然,通信应该加密,但我真的不知道服务器对服务器加密应该使用哪种加密。我现在使用的协议是TCP via net.createServer。假设两台设备上都有已交换的密码,我应该如何加密通信?我如何使其安全到最已知的攻击 编辑: 将RSA与“身份验证密码”结合使用是否安全?然后,每次请求时都会提交此密码,整个消息(包括密码)将使用RSA公钥加密(可以不加密下载)。我认为正确的方法是通过ssl进行通信,请

我想创建一个Node.js守护进程,它运行在多台计算机上,并且能够在不同的守护进程之间交换消息。当然,通信应该加密,但我真的不知道服务器对服务器加密应该使用哪种加密。我现在使用的协议是TCP via net.createServer。假设两台设备上都有已交换的密码,我应该如何加密通信?我如何使其安全到最已知的攻击

编辑:
将RSA与“身份验证密码”结合使用是否安全?然后,每次请求时都会提交此密码,整个消息(包括密码)将使用RSA公钥加密(可以不加密下载)。

我认为正确的方法是通过ssl进行通信,请参见此处:

您还可以使用加密模块进行快速加密:

var crypto = require('crypto'); 
var algorithm = 'aes256'; // or any other algorithm supported by OpenSSL

exports.encryptString = function(text) {

var cipher = crypto.createCipher(algorithm, key);
return cipher.update(text, 'utf8', 'hex') + cipher.final('hex');

};

var key = "123456"; 

exports.decryptString = function(text) {

var decipher =  crypto.createDecipher(algorithm, key);
return decipher.update(text, 'hex', 'utf8') + decipher.final('utf8');

};
两台服务器都需要公钥


您可能希望在上面使用JSON stringify和parse函数(我有这些函数)。您可以在中间件中完成这项工作,该中间件可以破译传入请求和传出请求的密码。

我采用了一种不同的方法,在我的应用程序之外完成这项工作。一般来说,您不想重新发明轮子,安全加密是一件很难做到的事情

在这种情况下,几个从属服务器需要与主服务器通信以从队列运行作业。对于服务器到服务器的连接,我实际上只是使用(使用和禁用除web套接字之外的所有传输)。这给了我一个坚实的RPC,它可以很好地满足我的需要。(我后来发现了一种可以在任意流上实现RPC的方法。对于Socket.IO过于致命的服务器对服务器通信来说,这将是一种更为轻量级的方法。)

现在,对于加密部分…我只使用在服务器之间设置的VPN。我采用了懒惰的方法并用于此,但您肯定可以使用或任何其他方法

您可以使用的第二种方法是


简而言之,不要做任何你不需要做的工作。选择速度、简单性和安全性。为此,请使用现成的工具。

一个可能更容易实现的选项是通过使用预先共享的gpg密钥,对通过普通套接字连接(
net.createServer
net.connect
)发送的所有消息进行加密和解密。这要求您在客户端和服务器上的
$PATH
中都有
gpg
,服务器上有一个无密码的专用gpg密钥
'server'
,客户端上有一个相应的
'client'
,另一端安装了相应的公钥

server.js:

var socketServer = net.createServer(function (c) {
  // example of send to client
  var output = JSON.stringify({"msg": "Stuff to send to client."});
  encrypt(output, 'Client', function (error, cryptdata) {
    c.write(cryptdata.toString());
  });
  // receive data sent from client
  c.on('data', function (cryptdata) {
    decrypt(cryptdata.toString(), 'Server', function (error, data) {
      data = JSON.parse(data.toString());
      // handle incoming data
    });
  });
});
socketServer.listen(port, function() {
});
client.js:

var socketClient = net.connect({"port": port}, function () {
  // Send data to server
  var data = JSON.stringify({"msg": "Data to server"});
  encrypt(data, 'Server', function (error, cryptdata) {
    socketClient.write(cryptdata.toString());
  });
});
// Receive data from server
socketClient.on('data', function(cryptdata) {
  decrypt(cryptdata.toString(), 'Client', function (error, data) {
    data = JSON.parse(data.toString());
    // handle data
  });
});
这些是我在server.js和client.js中用于加密/解密的函数

function encrypt(str, receiver, callback) {
  gpg.encrypt(str, ['-r ' + receiver, '-a'], callback);
}
function decrypt(str, receiver, callback) {
  gpg.decrypt(str, ['-u ' + receiver, '-a'], callback);
}

这消除了使用自签名SSL证书时可能遇到的任何问题,至少使用我的基准测试,速度要快得多。不过,它可能不那么安全。

对于您的特定情况,它可能是正确的,但不幸的是,我不能使用这种方法,因为“我的”服务器无法配置为使用vpn。这个应用程序的结果应该更像是一个对等消息系统,而不是预先配置好彼此vpn连接的预定义服务器。@FlorianW。啊,这是有道理的。在这种情况下,直接使用SSL可能更合适。如果可能的话,我仍然会考虑SSH隧道。这是不可能的,因为服务器应该是在多个操作系统上。@ FlorianW。SSH在所有操作系统上都非常有效。但是是的,如果你把这些都放在你的应用程序中,它会更加独立。这里有一个更新的链接:在使用TLS/SSL时,如何验证没有购买SSL证书的其他服务器?看起来它可能会拒绝deault的自签名证书,但您可以像这样覆盖此行为:process.env.NODE\u TLS\u reject\u UNAUTHORIZED=“0”互联网上似乎有很多关于这类事情的讨论,但这会让每个人都很容易伪造证书,从而允许中间人攻击。另外:您确定您提供的函数输出的AES有效吗?我无法在使用同一密钥的情况下通过使用或类似的站点进行验证。这不是我的专业领域,但在我看来,默认情况下,不允许使用自签名证书,所以您最好没有?不确定我的小函数是否生成有效的AES,这里似乎说您希望在加密模块中使用稍微不同的函数: