Node.js server-to-server encryption

旧城冷巷雨未停 提交于 2019-12-22 12:56:15

问题


I want to make a Node.js daemon that runs on multiple computers and is able to exchange messages between the different daemons. Of course the communication should be encrypted, but I really don't know what kind of encryption I should use for server-to-server encryption. The protocol I'm using right now is TCP via net.createServer. How should I encrypt the communication assuming I have a already exchanged password on both devices? How do I make it secure to the most known attacks?

Edit: Is using RSA combined with an "authentication password" secure? This password would then be submitted with every request, the whole message (including the password) would be encrypted with the RSA public key (which can be downloaded without encryption).


回答1:


I think the right way to do this is to communicate via ssl, see here:

http://nodejs.org/docs/v0.4.2/api/tls.html

You could also do a quick and dirty encryption using the crypto module:

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');

};

Both servers need the public key.

You'll probably want to use JSON stringify and parse functions on top of the above (I had those lying around). You could do it in middleware that deciphers incoming requests and ciphers outgoing ones.




回答2:


I take a different approach to this by doing the work outside of my application. Generally speaking, you don't want to reinvent wheels and secure encryption is a tough thing to get right.

I have a situation where several slave servers need to communicate to a master server to run jobs from a queue. For the server-to-server connection I actually just use Socket.IO (using the socket.io client NPM package and all transports disabled except for web sockets). This gives me a solid RPC, which works well for my needs. (I have since discovered rpc-stream which can give you RPC over arbitrary streams. This would be a bit more lightweight for server-to-server communication where Socket.IO is overkill.)

Now, for the encryption part... I just use a VPN set up between my servers. I took the lazy approach and used Hamachi for this, but you can certainly use OpenVPN or any other.

A second method you can use is to tunnel your connections through SSH.

In short, don't do any work you don't have to. Opt for speed, simplicity, and security. Use something off-the-shelf for this.




回答3:


One option which might be easier to implement is to encrypt and decrypt all messages sent over a normal socket connection (net.createServer and net.connect), via pre-shared gpg keys using node-gpg. This requires that you have gpg in your $PATH on both client and server with a password-less private gpg key 'Server' on the server and a corresponding 'Client' on the client, with the respective public keys installed on the other end.

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
  });
});

And these were the functions I used in both server.js and client.js for encryption/decryption.

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

This eliminates any problem you may run into with self-signed SSL certificates and at least with my benchmarks it is a lot faster. Though, it might not be as secure.



来源:https://stackoverflow.com/questions/22738754/node-js-server-to-server-encryption

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!