Node.js& Socket.io:安全websocket连接的自签名证书

时间:2014-03-23 16:57:19

标签: javascript node.js security sockets socket.io

我一直在互联网上寻找直接的答案,但大多数解决方案都涉及使用Express并提供HTTP内容以实现安全连接。我对Node.js和socket.io的安全Web套接字连接( wss >更感兴趣

我没有将Node.js用于HTTP请求。我使用与Node.js一起使用的socket.io模块将消息实时传递给我的应用程序。我只使用节点进行Web套接字连接。

我会简单解释一下我的设置是什么。我使用Django作为我的HTTP后端。用户向Django发出请求,Django将该请求的内容转发给Redis,Node.js在Redis的一个频道上进行侦听,处理内容并将消息发送给相应的收件人。

非常简单直接。一切正常。但我担心与Node.js的websocket连接是不安全的。当Node.js向收件人发送消息时,我不希望任何人在其间窥探并拦截该消息。我想确保我的用户感到安全并相信我为他们建立的服务。

我查看了CA的自签名证书和证书。两者都提供相同级别的安全性。由于我只使用Node.js作为socket.io并且不提供HTTP内容,因此自签名证书将完全正常工作(我构建的服务是针对移动设备而非浏览器!)

以下是我对socket.io的实现:

var io = require('socket.io').listen(8000);
var redis = require('socket.io/node_modules/redis')
var redisChannelConnection = redis.createClient(6000, "12.345.678.9");
var redisServer = redis.createClient(6000, "23.456.789.1");

// Subscribe to Redis Channel
redisChannelConnection.subscribe('messages');

io.sockets.on('connection', function (socket) {
     socket.emit('message', 'Hello World');
     }

到目前为止,我刚刚编写了一个简单的连接函数。它可以作为普通的websocket连接。但我想将其设为安全的websocket连接。我有多少人这样做?

感谢您的帮助。

3 个答案:

答案 0 :(得分:7)

首先,您需要在节点中创建HTTPS服务器(您需要证书):

http://nodejs.org/api/https.html
How to create an HTTPS server in Node.js?

然后你应该使用该服务器来启动Socket.io。

var io = require('socket.io').listen(myHTTPSserver);

基本上应该是它的所有内容。

有两种方法可以保护您的连接免受中间人攻击:

  • 使用签名证书,让客户端检查该签名。互联网上充斥着解释为什么这实际上是一个非常糟糕的解决方案。
  • 确保客户端拒绝连接除证书之外的任何内容。任何正常的SSL / TLS库都允许您指定必须用于传出连接的证书,如果服务器端的密钥与该证书不匹配,则连接将被中止。这可以完成签名系统应该做的所有事情,但不依赖于世界上每一个CA证书都是诚实的,或CA系统的任何其他缺点。

您的Django / Node.js组合听起来很奇怪,是否正确理解客户端在一个通道上发出请求并在另一个通道上接收响应?

虽然它在技术上可以正常,但它听起来像是制造奇怪漏洞的秘诀。如果必须同时使用两者,请考虑将Node作为Django内容的代理,并让Node处理所有身份验证。

在任何情况下,我都非常怀疑加密两个频道中的一个就足够了,一旦黑客攻击了一个频道,很可能会出现过多的升级选项。

答案 1 :(得分:2)

  

我查看了CA的自签名证书和证书。   两者都提供相同级别的安全性。

不,他们不是。如果您执行HTTPS(例如SSL内部的HTTP)或wss(例如SSL内部的HTTP隧道内的套接字类型),则SSL的安全性无关。 SSL提供端到端加密,但只有在能够识别另一端的情况下才能保证端到端。这是证书的用途。由受信任的CA签名的证书表示某些CA查看了证书数据,并确保证书中的数据与所有者匹配。但是一张自签名的证书只是说,所有者本身认为一切都很好,但是没有人信任它。这就是默认情况下不受信任的自签名证书的原因,并且每个用户必须明确信任证书(希望在他以某种方式验证了所有者之后)。

答案 2 :(得分:1)

首先,我完全同意另一个答案,即自签名证书不那么安全,但稍后会更多......你想要做的是需要“https”而不是“http”和{{3创建您的HTTPS应用程序。选项与pass in your certificate options into createServer几乎相同。然后当你调用listen.io时,你将通过HTTPS而不是HTTP进行监听。

现在回到真正的问题,这是对CA的目的的误解。我同意即使是自签名证书也会对内容进行加密,但是自签名证书不会被其他任何人验证,这意味着任何其他人都可以生成自己同样有效的自签名证书。咖啡店的恶意用户可以建立似乎合法的WiFi网络。在控制该网络时,他可以将自己置于所有请求的中间。他所要做的只是为您的域名生成自己的自签名证书,他不仅可以解密,还可以在传输过程中修改所有请求。这不仅适用于浏览器,也适用于Android,iPhone或其他任何移动应用。证书颁发机构适用于操作系统,以指示哪些根证书可信任颁发证书。由于恶意用户无法在受信任的证书颁发机构注册您的域名证书,因此以这种方式验证的任何证书都可以保证另一端的计算机实际上是目标计算机。自签名证书在开发中很好,但在生产中使用它们会使通过您的应用程序发送的任何数据面临欺骗您的服务器,信息泄露和消息篡改的风险。