HTTPS安全协议解析以及基于nodejs搭建https服务
- HTTPS原理
- HTTPS域名配置与证书申请
- nodejs配置证书启动HTTPS服务
- HTTPS服务可能需要解决的问题与潜在的安全问题
一、HTTPS原理
HTTPS有被称为HTTP安全协议,在HTTP协议的基础上增加一层安全层,也就是在HTTP应用层与TCP传输层之间增加一层加密与认证流程,确保通讯的安全。这一层协议也通常被称为SSL(Secure Sockets Layer安全套接层),或者也可以说是其后继者TLS(Transport Layer Security传输层安全),这两者总体上的加密逻辑差一步,具体的安全加密细节不是这篇博客讨论的主要内容。所以后面如果出现SSL或者TLS的话将他统一视作安全层即可。
1.1HTTPS的加密过程
从上面这个HTTPS加密流程中可以看到一些关键字:证书、证书公钥、证书私钥、(会话)密钥、加密、解密。这些关键字都指向一个问题——加密策略。这些关键字反映出了一系列的加密技术:对称加密、非对称加密、混合加密、会话密钥、数字证书、数字签名。下面就先来一个个了解它们,然后再详细的解析整个加密流程。
1.1.1密码:使用加密算法实现加密编码,是偷窥者无法识别加密后的数据内容。
密码学是一套编码方案,一种特殊的报文编码方式和一种稍后使用的相应解码方式的结合体。加密之前的原始报文叫做明文(plaintext或cleartext),使用了密码之后的报文被称为密文。
在数千年前尤利乌斯·凯撒就是用三字符循环移位密码,报文中的每个字符都由字母表中的三个位置之后的字符来取代,用现代字母表中的“A"就应该由“D"取代,”B"就应该由“D”取代,以此类推,也就是rot3(三位循环移位)。假设报文内容“meet me at the pier at midnight”,编码为密文就应该是“phhw ph dw wkh slhu dw plgqljkw”。
这是几千年前的密文编码技术,全部依靠手动编码解码,在现代计算机算法中非常容易实现,但也就非常容易被破解,后来再简单的循环移位基础上增加了旋转、替代字符、改变字符顺序、将报文切片,使代码破解难度更加困难,但是随着技术的发展很多编码和解码算法都相对透明了,这类密码技术还是非常容易被破解。再后来在这些技术的基础增加了密钥值。
密钥值就是指在对数据进行加密编码时,加密和解密都需要使用这个密码作为算法的参数,数据在使用密钥计算加密后,同样需要使用一个密钥作为参数解密。在这一基础上发展出了对称密钥加密和非对密钥称加密。
1.1.2对称密钥加密:编码器与解码器都是用同一个密钥进行加密和解密,流行的对称密钥加密算法包括:DES、Triple-DES、RC2、RC4。
对称密钥加密对于密钥的机密性就显得非常重要了,如果发生密钥泄密就是灾难性的事件,除了人为或者技术漏洞导致的泄密以外,对称密钥加密技术在现代计算机技术高度发达的今天来说,还将面对暴力的枚举攻击。
枚举攻击就是使用计算机将可能的密钥一个个代入解码器,直到计算出真正的密钥值。48位的密钥只有256个可能的密钥值,这对于现代计算机来说枚举攻击简直轻而易举,40位密钥可以有240(约一万亿个密钥)个可能,如果要使用枚举攻击破解这个位数的密钥就要付出一些代价了,也就是说对称密钥加密技术密钥位数越大相对越安全,而这也仅仅是相对而言,这还需要考虑加密数据的标的物价值。
1.1.3非对称密钥加密:编码器与解码器使用不同的密钥进行加密和解密,非对称加密又称为公开密钥加密技术。非对称密钥加密在对数据加密和解密时应用了两个密钥,也就常说的公钥和私钥,公钥是对外公开的,提供给会话方加密要发送给自己的数据,当接收到公钥加密的数据后使用私钥解密。在完成一个双向通讯的过程中,需要两个非对称密钥协同完成。比较经典的非对称密钥加密技术有:RSA。
注意:一个非对称密钥包含一个公钥和一个私钥。
向对于对称密钥加密,非对称密钥加密解决了密钥交换问题,在对称密钥加密中存在一个问题就是双方如何沟通密钥问题,谁来保证密钥的私密性不被破坏这些都是巨大的挑战,而采用非对称加密却完美的解决了这个问题。但是非对称加密的计算量非常大,对于系统性能是巨大的挑战,我们知道在web应用中网络资源实非常珍贵的,如果一个连接响应时间过长可能出现中断连接的可能,即便我们可以通过修改连接最大时间值也不是明智的选着。因为这样同样伴随着巨大的系统资源开销,所以HTTPS并没有完全使用对称加密,而只是在SSL握手过程中采用非对称加密技术,而在实际的会话时使用的是对称加密技术,相关内容在后面的内容中详细解析。
1.1.4数字签名:数字签名在HTTPS中准确来说应该是报文数字签名,单纯的数字签名就是通过算法基于数据本身获取数据的一部分作为数据摘要,可以作为数据的唯一性的身份证明标识。
数字签名技术是基于数据生成一个唯一值,当数据发生改变时,这个值就必然发生改变,而且在HTTPS中签名函数还是用了私钥作为签名函数的参数,所以如果要伪造签名就必须拥有私钥才能完成。接收方使用公钥和签名反函数基于数据同样可以计算出这个签名,如果计算出的签名一致就可以确定数据没有发生改变,并且也可以确定对方的身份是正确的。
第一步:A使用私钥A基于明文报文计算出报文摘要(签名)。
第二步:B收到并解析出报文明文和A的签名。
第三步:B使用签名反函数和公钥A基于明文报文计算报文摘要,并与签名对比,如果摘要相同则说明报文内容没有发生改变,并且数据是来源A。反之则不是安全数据,弹出警告并中断会话。
数字签名起到了对报文安全的验证效果,确保数据发送方的身份和数据是否安全。
1.1.5数字证书:数字证书中包含一组信息,所有这些信息都由一个官方的“证书颁发机构”以数字签名的方式签发。基本的数字证书通常包含以下内容。
对象的名称:个人用户、服务器、组织。
过期时间:证书的有效期。
证书发布者:由谁为证书担保。
证书数字签名:来自颁发者对证书的数字签名。
除了基本信息和典型格式中的内容以外,一般还会包括发布者的唯一ID和对象的唯一ID。
数字证书是用来证明连接的是安全可靠的主机,通过证书内容验证主机的安全性是否是可信任的主机,除了验证主机的可靠性还需要验证证书是否可靠,数字证书从内容上来说并不是多么复杂的内容,一般普通主机都可生成对应格式的内容,但从web事务来说浏览器如何确定证书说明的主机就是可靠的呢?所以这就需要第三方权威的证书机构来颁发,浏览器会通过向第三方证书验证来确定证书的真伪,但这类验证也只是定期更新各个权威机构的证书序列号,通过验证证书序列号是否有效的普通验证手短。
除了确定证书序列号是有效的以外,浏览器还会根据证书颁发机构的公开密钥采用证书签名反函数计算出证书摘要(证书的数字签名),与证书中的数字签名对比来验证证书的真伪。(这与前面的报文数字签名技术原理一致,权威的数字证书颁发机构回对浏览器公开机构的公开密钥)
1.1.6HTTPS的安全传输握手过程(SSL):
前面已经对HTTPS的加密技术进行了逐个的解析:对称加密、非对称加密、数字签名、数字证书,接下来再来了解以下HTTPS的安全传输握手过程,在了解SSL之前有必要先了解整个HTTPS会话流程。
HTTPS会话流程解析:
1、客户端首先打开一条到Web服务器端口443(HTTPS默认端口)的连接,建立TCP连接。
2、建立连接后,客户端与服务器就初识化SSL层,对加密参数进行沟通,并交换密钥。(这个步骤比较复杂,其中包括证书验证、协商加密算法、生成使用对称加密技术的报文密钥、采用非对称加密交换报文密钥、报文数字签名,后面回对SSL握手进行详细的解析)
3、SSL握手完成以后,客户端将请求报文发送给安全层(SSL)。
4、SSL层使用报文密钥报文加密后,交由TCP连接发送给服务器。
5、服务器收到请求后,使用报文密钥解密请求报文,解析请求报文。
6、服务器取出请求对应的数据资源,交由SSL层使用报文密钥加密响应报文,通过TCP连接发送给客户端,在加密之前还会生成一个报文签名然后交给SSL统一打包。
7、客户端收到响应报文后,使用报文密钥解密响应报文,拿到报文后使用数字签名反函数并以服务器公钥作为参数计算出报文的数字签名,然后与服务器发送过来的数字签名进行对比验证,验证通过后将数据交由程序处理,如果验证不通过弹出警告并进入HTTPS会话关闭流程。
8、SSL关闭通知、TCP关闭连接。
1.1.7SSL握手详解:
SSL握手是HTTPS协议的核心部分,它负责验证网络连接的双方身份,并在客户端生成报文密钥再用服务的公钥加密传送给服务,在这个过程中采用的是非对称加密。虽然SSL支持双向认证,但一般web项目只对服务器进行认证,并不使用客户端证书对用户进行认证,一些安全性要求较高的系统会要求使用客户端证书认证(网银U盾)。
SSL握手流程解析:
1.当客户端发起HTTPS请求时,向服务器发送一个随机值和客户端支持的加密算法集。
2.服务器收到请求后,挑选双方都持支的加密算法,并和服务器证书以及服务器端生成的随机值一起响应给客户端。
3.客户端收到响应后,对证书进行验证:证书日期检查、证书颁发者可信度、签名检测(签名反函数)、站点身份检查(检查证书的内容与实际请求的站点是否一致)。如果发现任意环节出现数据不匹配的情况,就会报错误提示并结束会话。如果一切检测通过,就使用本地和服务器生成的随机值基于服务器确认的双方都支持的加密算法生成报文密钥。然后使用从服务器证书中解析出来的服务器公钥加密报文密钥和HTTPS的请求信息发送给服务器,这个环节使用的是非对称加密。
4.服务器收到加密报文后使用服务器私钥解密报文,解密报文取出报文密钥和请求内容,然后把客户端请求的数据通过报文密钥加密,并且同时产生一个报文数字签名发送回客户端。(响应请求资源环节使用对称加密)
5.客户端收到资源响应报文后使用报文密钥解密,使用签名反函数对报文签名进行检测,检测通过后才会解析报文携带的资源数据并刷新页面,如果检测不通过同样会报错误提示并结束会话。
二、HTTPS域名配置与证书申请
证书提供商比较多,比如全球知名安全证书提供商赛门铁克(symantec),其他还有阿里云、腾讯云、西部数据、亚马逊、沃通。至于怎么选择不是这里要讨论的,如果只是做测试的话建议找一个免费的就好,接下来看看如何配置证书。
首先准备一个域名,配置域名解析我就不在这里讲了。接下来我用腾讯云的SSL免费证书配置为例:
第一步:申请证书,域名和邮箱必填,然后选择下一步。
第二步:域名身份认证,选择手动DNS验证,然后确认申请。
第三步:确认申请后,会进入证书基本信息页面,将证书信息中的DNS域名解析配置到域名解析中。
第四步:手动到域名控制台配置证书解析,将证书的DNS验证信息添加到对应的域名解析中,就可以了。
第五步:然后回到证书信息详情页查询解析是否成功。
第六步:如果证书验证解析成功了,就等着证书颁发机构给你颁发证书了,这可能需要等一些时间,有些朋友说有的机构需要等一个星期,但我只用了不到一分钟就可以了。
第七步:下载证书,别问我下载干嘛,你说干嘛,当然是用来搭建HTTPS服务了。
下载证书后,后面的内容就是下一节的了,配置HTTPS服务。
三、nodejs配置证书启动HTTPS服务
下载的证书包含多种服务的配置:Apache、IIS、Nginx、Tomcat,各自根据自己的服务搭建,这里因为我是用的时win环境,也懒得安装其他服务了,就直接使用IIS服务的配置。
这里我先将证书所有内容解压到了SSL路径下,下面最简单的配置代码index.js,然后使用node启动index.js
1 //index.js 2 let https = require("https"); 3 let fs = require("fs"); 4 let options = { 5 pfx: fs.readFileSync("./SSL/IIS/xxxx.com.pfx"), 6 passphrase: 这里将ISS下的keystorePass.tex中的密钥复制到这里,注意时字符串类型 7 } 8 https.createServer(options,function (request,response) { 9 response.writeHead(200); 10 response.write("<html><meta charset=\"UTF-8\"><title>HTTPS安全服务测试</title><head><body></head><h1>HTTPS安全服务已启动!</h1></body></html>") 11 response.end(); 12 }).listen(12306);
当服务器正常启动后,在浏览器使用访问:https://你的域名:12306
当你看到地址栏前面的锁时,就表示你请求的网站是HTTPS安全协议,其实配置起来与http没啥区别,就是在createServer方法中多了一个options的参数,这个参数可以从代码中看到就是用来解析SSL证书的,其他的HTTP怎么来,HTTPS还是一样的操作。关于HTTPS的其他服务的配置在网上也有比较多的教程,我暂时就不一个个的演示了,最近计划自己弄一个博客网站,如果到时候有时间的话,可能会在我自己的博客网站中补充。
四、HTTPS服务可能需要解决的问题与潜在的安全问题
1.在使用HTTPS服务的时候,在一些大型项目中可能出现多个服务器处理请求,而一个站点又只有一个证书,这种情况可以在开始处理安全事务之前重定向到一个主机上。
2.HTTPS绝对安全吗?答案是不可能保证绝对安全!但相对HTTP请求来说要安全很多,那HTTPS不安全的可能因素有哪些呢?
- 中间人攻击:从前面的https的请求解析中可以了解到https的请求本质上是由http层传送给SSL层,在这之间本质上还是明文。而这个环节最容易被攻击的就是SSL握手的第一个环节,当请求发送出去后还没到达SSL层的时候就被拦截,这时候攻击者如果将请求主机修改成了另一个也具有SSL证书的服务器地址,这时候攻击者就可以伪装成你实际请求的站点,实现这类攻击的方式可以通过劫持DNS服务器来实现。
- 枚举攻击:除了中间人攻击对于HTTPS的加密算法进行暴力破解枚举攻击依然是可以实现的,只是就目前来说这种攻击是非常不划算的方式,假设攻击者要投入10万元成功攻击破解获取数据缺只价值1万元,这种攻击显然即便可行也不会有人采用,但如果数据标的物价值远远超过10万呢?所以说加密其本质也是一种博弈。
3.HTTPS的性能相对HTTP来说要差一些,据卡内基梅隆大学的一份研究量化了“S”的代价,HTTPS加载时间增加了50%,增加10%~20%的耗电,还会影响缓存以及现有的安全措施。
4.增加开发成本,假设一个页面的数据来源多个网站或者项目呢?这时候需要解决的问题就会比较复杂,这个问题好像跟第一个问题有点类似,可以肯定这会带来开发成本的提高。
5.搜索引擎对于HTTPS的协议抓取不够友好,会影响到站点的搜索排名。