简体   繁体   English

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

[英]Node.js & Socket.io: Self-signed certificates for a secure websocket connection

I've been running across the internet looking for a straight forward answer, but most solutions involve using Express and serving HTTP content for secure connections. 我一直在互联网上寻找直接的答案,但大多数解决方案都涉及使用Express并提供HTTP内容以实现安全连接。 I'm more interested in a secure web socket connection ( wss ) for Node.js and socket.io 我对Node.js和socket.io的安全Web套接字连接( wss )更感兴趣

I don't use Node.js for HTTP requests. 我没有将Node.js用于HTTP请求。 I use the socket.io module that works with Node.js to deliver messages in real time to my applications. 我使用与Node.js一起使用的socket.io模块将消息实时传递给我的应用程序。 I only use node for the web socket connection. 我只使用节点进行Web套接字连接。

I'll explain breifly what my setup is. 我会简单解释一下我的设置是什么。 I use Django as my HTTP backend. 我使用Django作为我的HTTP后端。 Users make a request to Django, Django forwards the contents of that request to Redis, Node.js listens in on one of Redis' channels, it processes the contents and sends the message to the appropriate recipient. 用户向Django发出请求,Django将该请求的内容转发给Redis,Node.js在Redis的一个频道上侦听,它处理内容并将消息发送给适当的收件人。

Pretty simple and straight forward. 非常简单直接。 Everything works fine. 一切正常。 But I'm afraid that the websocket connection to Node.js is unsecure. 但我担心与Node.js的websocket连接是不安全的。 When Node.js sends a message to the recipient, I don't want anyone snooping in between and intercepting the message. 当Node.js向收件人发送消息时,我不希望任何人在其间窥探并拦截该消息。 I would like to make sure my users feel safe and trust the service I have built for them. 我想确保我的用户感到安全并相信我为他们建立的服务。

I looked into self-signed certificates and certificates from a CA. 我查看了CA的自签名证书和证书。 Both provide the same level of security. 两者都提供相同级别的安全性。 Since I am only using Node.js for socket.io and not serving HTTP content, a self-signed certificate will work absolutely fine (the service I have built is for mobile, not for browsers!) 由于我只使用Node.js作为socket.io并且不提供HTTP内容,因此自签名证书可以正常工作(我构建的服务是针对移动设备而不是针对浏览器!)

Below is my implentation of socket.io: 下面是我对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');
     }

I have just written up a simple connection function so far. 到目前为止,我刚刚编写了一个简单的连接函数。 It works as a normal websocket connection. 它可以作为普通的websocket连接。 But I would like to make it a secure websocket connection . 但我想使它成为一个安全的websocket连接 How many I go about doing this? 我有多少这样做?

Thank you for your help. 谢谢您的帮助。

First you need to create an HTTPS server in node (for which you need a certificate): 首先,您需要在节点中创建HTTPS服务器(您需要证书):

http://nodejs.org/api/https.html http://nodejs.org/api/https.html
How to create an HTTPS server in Node.js? 如何在Node.js中创建HTTPS服务器?

Then you should use that server to initiate Socket.io. 然后你应该使用该服务器来启动Socket.io。

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

That should basically be all there is to it. 基本上应该是它的全部内容。

There is two ways to secure your connection from man-in-the-middle attacks: 有两种方法可以保护您与中间人攻击的连接:

  • Using a signed certificate, and having the client check that signature. 使用签名证书,让客户端检查该签名。 The internet is stuffed with explanations for why this actually a pretty poor solution. 互联网上充斥着解释为什么这实际上是一个非常糟糕的解决方案。
  • Making sure that the client refuses to connect with anything but your certificate. 确保客户端拒绝连接除证书之外的任何内容。 Any decent SSL/TLS library will allow you to specify a certificate that must be used for an outgoing connection, if the key on the server end doesn't match that certificate the connection is aborted. 任何正常的SSL / TLS库都允许您指定必须用于传出连接的证书,如果服务器端的密钥与该证书不匹配,则连接将被中止。 This does everything that the signature system should do, but doesn't rely on every single CA cert in the world being honest, or any of the other shortcomings of the CA system. 这可以完成签名系统应该执行的所有操作,但不依赖于世界上每个单独的CA证书,或者CA系统的任何其他缺点。

Your Django/Node.js combination sounds quite odd, is it correctly understood that clients make requests on one channel and receive the response on another channel? 您的Django / Node.js组合听起来很奇怪,是否正确理解客户端在一个通道上发出请求并在另一个通道上接收响应?

While it could technically be okay, it sounds like a recipe for making odd vulnerabilities. 虽然它在技术上可以没问题,但它听起来像是制造奇怪漏洞的秘诀。 If you must use both, consider making Node a proxy for the Django content and have Node handle all authentication. 如果必须同时使用两者,请考虑使Node成为Django内容的代理,并让Node处理所有身份验证。

In any case, I seriously doubt that encrypting just one of two channels is enough, once a hacker has pwned one channel there will most likely be a plethora of escalation options. 在任何情况下,我都非常怀疑加密两个频道中的一个就足够了,一旦黑客已经在一个频道上进行加密,很可能会出现过多的升级选项。

I looked into self-signed certificates and certificates from a CA. 我查看了CA的自签名证书和证书。 Both provide the same level of security. 两者都提供相同级别的安全性。

No, they don't. 不,他们没有。 The security of SSL has nothing to do if you do HTTPS (eg HTTP inside SSL) or wss (eg kind of socket inside HTTP tunnel inside SSL). 如果您执行HTTPS(例如SSL内部的HTTP)或wss(例如SSL内部的HTTP隧道内的套接字类型),则SSL的安全性无关。 SSL provides end-to-end encryption, but this end-to-end can only be guaranteed if you can identify the other end. SSL提供端到端加密,但只有在能够识别另一端的情况下才能保证端到端。 That's what certificates are for. 这就是证书的用途。 A certificate signed by a trusted CA means, that some CA looked at the certificate data and kind of made sure that the data in the certificate matches the owner. 由受信任的CA签名的证书表示某些CA查看了证书数据,并确保证书中的数据与所有者匹配。 But a self-signed certificate just says, that the owner itself thinks that everything is fine, but nobody trusted had a look at it. 但是一张自签名的证书只是说,所有者本身认为一切都很好,但是没有人信任它。 This is the reason self-signed certificates are not trusted by default and each user has to explicitly trust the certificate (hopefully after he has validated the owner somehow). 这就是默认情况下不受信任的自签名证书的原因,并且每个用户必须明确信任证书(希望在他以某种方式验证了所有者之后)。

First, I completely agree with the other answer that self-signed certificates are not as secure but more on that in a moment... What you want to do is require "https" instead of "http" and pass in your certificate options into createServer to create your HTTPS app. 首先,我完全同意另一个答案,即自签名证书不是那么安全,但稍后会更多......你想要做的是需要“https”而不是“http”并将你的证书选项传入createServer来创建您的HTTPS应用程序。 The options are pretty much the same as the TLS options here . 这些选项与此处TLS选项几乎相同。 Then when you call listen for socket.io, you'll be listening via HTTPS instead of HTTP. 然后当你调用listen.io时,你将通过HTTPS而不是HTTP进行监听。

Now back to the real issue which is a misunderstanding of the purpose of the CA. 现在回到真正的问题,这是对CA的目的的误解。 I agree that even a self-signed certificate will encrypt the content, but a self-signed certificate is not validated by anyone else meaning that anybody else can generate their own self-signed certificate that is just as valid. 我同意即使是自签名证书也会对内容进行加密,但是自签名证书不会被其他任何人验证,这意味着任何其他人都可以生成自己同样有效的自签名证书。 A malicious user at a coffee shop could set up a WiFi network that seems legitimate. 咖啡店的恶意用户可以建立似乎合法的WiFi网络。 In control of that network he can put himself in the middle of all requests. 在控制该网络时,他可以将自己置于所有请求的中间。 All he would have to do is generate his own self-signed certificate for your domain name and he would be able to not only decrypt, but also modify in transit all of the requests. 他所要做的只是为您的域名生成自己的自签名证书,他不仅可以解密,还可以在传输过程中修改所有请求。 This applies not just to browsers, but also mobile apps for Android, iPhone or anything else. 这不仅适用于浏览器,也适用于Android,iPhone或其他任何移动应用。 The certificate authority is in place for operating system to dictate which root certificates are trusted to issue certificates. 证书颁发机构适用于操作系统,以指示哪些根证书可信任颁发证书。 Because the malicious user can't register a certificate for your domain name at a trusted certificate authority, any certificate validated in that way guarantees that the computer on the other end is in fact the intended computer. 由于恶意用户无法在受信任的证书颁发机构注册您的域名证书,因此以这种方式验证的任何证书都可以保证另一端的计算机实际上是目标计算机。 Self-signed certificates are fine in development, but using them in production puts any data sent via your application at risk of spoofing your server, information disclosure, and message tampering. 自签名证书在开发中很好,但在生产中使用它们会使通过您的应用程序发送的任何数据面临欺骗您的服务器,信息泄露和消息篡改的风险。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM