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

我一直在互联网上寻找一个简单的答案,但大多数解决scheme涉及到使用快递和服务HTTP内容的安全连接。 我对Node.js和socket.io的安全web套接字连接( wss )更感兴趣

我不使用Node.js来处理HTTP请求。 我使用与Node.js一起使用的socket.io模块来实时向我的应用程序传递消息。 我只使用节点的networking套接字连接。

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

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

我查看了来自CA的自签名证书和证书。 两者都提供相同的安全级别。 由于我只使用Node.js作为socket.io而不提供HTTP内容,所以自签名证书将工作得非常好(我build立的服务是针对移动的,而不是针对浏览器的)。

以下是我的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连接 。 我有多less事情要做?

感谢您的帮助。

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

http://nodejs.org/api/https.html
如何在Node.js中创build一个HTTPS服务器?

那么你应该使用该服务器来启动Socket.io。

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

基本上应该是这一切。

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

  • 使用签名的证书,让客户检查签名。 互联网塞满了解释为什么这实际上是一个非常糟糕的解决scheme。
  • 确保客户端拒绝连接除证书以外的任何内容。 任何体面的SSL / TLS库将允许您指定必须用于传出连接的证书,如果服务器端的密钥与该证书不匹配,连接将中止。 这就是签名系统应该做的所有事情,而不是依赖世界上每一个诚实的CA证书或者CA系统的其他任何缺陷。

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

虽然技术上可以,但这听起来像是制造奇怪的漏洞的秘诀。 如果您必须同时使用,请考虑将Node设置为Django内容的代理,并让Node处理所有的身份validation。

无论如何,我严重怀疑只encryption两个频道中的一个频道就足够了,一旦黑客产生了一个频道,那么很可能会有很多升级选项。

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

不,他们不。 如果你使用HTTPS(例如SSL内部的HTTP)或者wss(例如SSL内的HTTP隧道内部的套接字),SSL的安全性无关紧要。 SSL提供了端到端的encryption,但只有在识别另一端的情况下才能保证端到端的安全。 这就是证书的用途。 由受信任的CA签署的证书意味着某些CA查看了证书数据,并确保证书中的数据与所有者匹配。 但是一个自签证书只是说,老板本身认为一切都很好,但没有人相信看过。 这就是自签名证书不被默认信任的原因,每个用户都必须明确信任该证书(希望在他以某种方式validation了所有者之后)。

首先,我完全同意另外一个答案,即自签名证书并不安全,但稍后更多…你想要做的是要求“https”而不是“http”, 并将你的证书选项传入createServer来创build您的HTTPS应用程序。 选项与这里的TLS选项几乎相同。 然后当你调用socket.io的时候,你将通过HTTPS而不是HTTP进行监听。

现在回到真正的问题,这是对CA的目的的一个误解。 我同意,即使是自签名证书也会encryption内容,但是自签名证书没有得到任何其他人的validation,即任何人都可以生成自己的自签名证书,这一点同样有效。 咖啡店里的恶意用户可能会build立一个合法的WiFinetworking。 在控制这个networking的时候,他可以把自己置于所有请求的中间。 他所要做的就是为自己的域名生成自己的自签名证书,他不仅能够解密,还能够在运输过程中修改所有的请求。 这不仅适用于浏览器,也适用于Android,iPhone或其他任何移动应用程序。 证书颁发机构适合操作系统来规定哪些根证书受信任颁发证书。 由于恶意用户无法在可信任的证书颁发机构为您的域名注册证书,因此以此方式validation的任何证书都能保证另一端的计算机实际上是预期的计算机。 自我authentication证书没有问题,但是在生产环境中使用它们会使得通过应用程序发送的任何数据都有可能欺骗你的服务器,泄露信息和消息篡改。