漫谈威胁建模下的安全通信
前言
这次文章的主要内容是一次内部技术分享的内容,主要是关于安全通信的威胁建模,设计方案以及算法,其中涉及https。一定要记得点好看哈。
通信的安全威胁与诉求
在讲解安全通信的方案之前,我们必须要知道通信有哪些安全威胁以及诉求,这样我们才能“对症下药”。根据微软提出的STRIDE威胁模型作为依据:
Spoofing(伪装)
Tampering(篡改)
Repudiation(抵赖)
Information Disclosure(信息泄露)
Denial of Service(拒绝服务)
Elevation of Privilege(提升权限)
STRIDE威胁模型几乎可以涵盖目前绝大部分安全问题,并且有着详细的流程和方法。每一个维度都对应的一个安全属性,也就是相应的安全诉求。
威胁 | 定义 | 安全诉求 |
---|---|---|
Spoofing | 冒充他人身份 | 认证 |
Tampering | 修改数据或代码 | 完整性 |
Repudiation | 否认做过的事情 | 不可抵赖性 |
Information Disclosure | 机密信息泄露 | 机密性 |
Denial of Service | 拒绝服务 | 可用性 |
Elevation of Privilege | 未经授权获得许可 | 授权 |
将威胁模型对应到安全数据通信上,前四个对我们来说更有意义,总结一下,安全通信的诉求包括:
完整性:通信的内容信息必须要完整,不可被篡改掉或者存在数据丢失;
机密性:通信的内容必须要得到有效的隐藏和保护,避免被泄漏到第三方;
认证性:包括实体认证和消息认证,其中实体认证是指通信的发送方和接收方是可信的未被假冒的,而消息认证是指消息是由认证过的实体用户发出的,不是被仿冒者发出的;
不可抵赖性:通信的数据携带有实体特质、不可被模仿复制的信息,确保通信数据是可确认的实体发出的。
接下来我们会根据对应的安全诉求来设计安全通信方案。
加密算法
在讲安全通信的方案之前,我们首先说一下通信加密算法,之后我们会使用这些算法来实现上面的安全诉求。
加密算法大体上可以分为三类:对称加密,非对称加密以及信息摘要。
对称加密
对称加密双方的通信密钥是统一的,特点是加解密效率高,而安全性就稍微弱一些。常见的算法例如AES,DES
非对称加密
特点是它拥有两个密钥,任意一个密钥都可以对信息进行加密处理,但是解密就需要用到另外一个密钥才能解析出正确的明文,安全性较高,但是效率低一些。常见的算法例如RSA,DSA。
信息摘要
特点是唯一性,不可逆,常见的算法例如MD5,SHA1。
HTTPS安全通信设计方案
下面咱们根据上述的安全诉求来拆解 HTTPS协议,在描述的过程中,大家肯定会有熟悉的感觉,既是拆解也是我们的设计。
完整性
完整性是靠信息摘要来保证的,将算出的摘要附到明文后,万一明文被修改,只要使用同样的算法得出明文摘要和原始摘要进行对比,不一样就证明被修改了。
但是在上图中,大家会发现,在生成摘要后,我们还会对摘要进行加密生成消息认证码。这是为什么呢?
备注:“通信消息+信息摘要+对称加密=数据验证码”的做法,就是通信中常见的MAC(Message Authorization Code,消息认证码)的实现。
大家可以想一下,如果我将明文修改,然后我又根据修改后的明文生成摘要,将原来的摘要替换掉,这样是不是依然无法发现明文已经被修改了,所以就有了之后的加密步骤。完整性也是需要机密性来保证的,相辅相成。
机密性
机密性在于通信的数据是否被加密,一般频繁的数据加解密,我们采用的是对称加密算法,对于服务器的消耗是很低的,这里的对称密钥我们称之为会话密钥(Session Key)。为什么称作会话密钥? 是因为每次建立通信连接都是随机生成一个对称密钥。会话通信既然是对称加密,那它的安全性是主要在于两点:
使用的对称加密算法是否安全,会不会被破解
对称密钥的交换过程是否安全,会不会被窃取
至于第一点,我们不会考虑这件事,这是密码学家的工作。对称密钥交换的安全是通信的关键,密钥在传输的过程中被窃取,那可真的是裸奔了。我们采用的是公私钥交换体系,下图是SSL/TLS协议握手建立连接的交换密钥简化过程。
在上图的第四步,通过随机数x,y,z生成了会话密钥,但是我们发现在前两步,x和y在传输过程中都是暴露的,因此会话密钥的安全性在于第三步的z的交换。
B使用了非对称加密算法,生成了一对公私钥,公钥交给了A,自己持有私钥。在密钥交换的过程中,A生成随机数z,通过B的公钥进行加密,B接收到数据,使用私钥进行解密得到z,从而保证了z的安全性,最终保证了会话密钥的安全性,防止在通信过程中被窃取。
一句话:通过非对称加密保证了对称加密的安全。
不可抵赖性
在经过完整性和机密性的加持后,通信数据是否就真的安全了?还是有风险。在机密性讲解过程中,我们知道会话密钥是通过公私钥的方式进行交换的,其中A用到了B的公钥,漏洞就在这:A获取B公钥的过程是安全的吗?这存在被劫持的可能性(例如DNS劫持),A获取到公钥不一定是B的,A可能会被伪造的B所欺骗。下图是利用这个漏洞进行的中间人攻击图:
通过劫持的方式,我们将随机数z在中途获取了,之后的加密通信基本上就是裸奔了,数据可以随便改。这就是http容易被DNS劫持的原因,那https是如何解决这个问题的呢?
这个问题的本质是A无法验证消息的来源是B,这就涉及不可抵赖性了。不可抵赖性的一般做法是使用数字签名,保证A获取的是B公钥,需要对B的公钥进行数字签名。
数字签名
下面描绘一下使用数字签名的场景,主角是A与B:
B手头有点紧,急需用钱,然后发邮件给A,邮件内容为:B借A 100万,银行卡号为xxxxxxx,这个时候A如果把钱打给B就会有以下风险:
邮件是可以伪造的,可能是诈骗团伙的发给A的
假如邮件确实是B发的,但是事后不承认,A也没有证据证明是B发。
如何解决A的困惑呢?在上述场景中,邮件就是我们所说的消息。在讲解机密性的时候,我们知道公钥是公开的,而私钥则是独有,隐蔽的,因此私钥是可以代表持有者的身份。
那么如果B把邮件的内容使用B的私钥进行加密,然后将加密后的密文即数字签名,附在邮件后面发给A,A这个时候只需要拿B的公钥解密数字签名,并和邮件原文进行比对,就可以确定是不是B发的了,这是非对称加密的特性,B私钥加密的,只有B的公钥才能解密,这就可以解决抵赖的问题了,哈哈哈。
看似完美。。。
在上述的解决方案中,有个巨大的漏洞:数字签名和公钥在传输中都是暴露的,不可信的,B的身份需要A拿B的公钥对数字签名进行解密来证明,那反问一下,A拿到的确定是B的公钥吗?假如B的公钥被篡改为C的,那么数字签名是不是有可能被篡改为由C的私钥进行加密的?
一身冷汗!!! 陷入了死循环,我们自以为解决了消息内容的抵赖问题,却没解决公钥的抵赖问题,从而导致消息内容的抵赖问题也无法解决,尴尬尴尬!!!
其实如果公钥的传输是可信的,那么数字签名还是可以解决抵赖问题的。想了一个好办法:
A 与B直接见面,互相把公钥交换一下,就可以。
开了个玩笑,两个人可以面对面,确实安全,但是很多人呢?不同的设备呢?面对面的成本实在太高了。
认证性
数字签名中遇到的尴尬,咱们对应到上面中间人攻击的那张图,出现劫持的问题原因是A无法验证B公钥的来源,假如是使用数字签名的话,那么B需要用自己的私钥对自己公钥进行签名,然后将签名附到公钥后面一起发给A。类似下图所示:
大家想一下是不是没什么用,由于公私钥可以互相加解密,中间人完全可以同时替换公钥和数字签名完成伪装。咱们可以思考一下,问题的症结在哪?数字签名用来识别消息篡改,伪装以及防止抵赖,但是我们又必须从没有被伪装的发送者得到没有被篡改的公钥才行,所以解决这个问题,就一句话:
在公钥传输不可信的情况下,数字签名这种证明身份的事情,不能让消息的双方来做。
举个现实中的例子,比如我们的公民身份证,身份证的签发是由公安机关来做的,给我们分配唯一标识身份证号,同时在数据库中存储与之对应的照片信息,这就是我们每个人的”数字签名“。如果身份证的签发由我们个人来做,那想伪造成谁都可以,同样 数字签名,我们需要找一个可信的第三方来做,这就涉及了认证性。
CA证书
认证性和不可抵赖性,他们相互依存,都处在HTTPS协议中的同一组件:CA证书。
备注:CA (数字证书认证机构):负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。
是不是感觉有点抽象?简单解释就是CA给B颁发了身份证,A拿着B的身份证去CA机构比对身份证合法性,从而确定B的身份。至于如何保证身份证的真实性,我们下面会讲。
首先看一下CA签发的证书长什么模样,其实就是一个文件。还是以B为例,下图是CA机构给B颁发的证书。
证书主要包括5个部分:
签发者信息CA
使用者信息B
B的密钥信息
B的公钥
数字签名
其中数字签名是由CA机构的私钥对证书上的信息(包括公钥)进行加密生成的。首先说一下,证书是如何解决上述问题的,以数字签名那一节中的场景为例:
1.B手头有点紧,急需用钱,首先通过邮件将自己在CA机构申请的证书发给A。
2.A收到邮件后,看到证书签发者的信息是CA,于是拿着证书找CA机构,CA机构用自己的公钥对数字签名进行解密,并比对使用者信息,密钥信息等内容。如果一致,说明这是给B签发的证书,公钥是B的。
3.接着B写邮件,邮件内容为:B借A100万,银行卡号为xxxxxxx,B把邮件的内容使用B的私钥进行加密,然后将加密后的密文即数字签名,附在邮件后面发给A,
4.A这个时候只需要拿B的公钥解密数字签名,并和邮件原文进行比对,就可以确定是不是B发的了
在上述场景中,基本上把证书的作用说明白了,当然https的实现方式会复杂一些,不过本质是一样的。我们看到通过证书的方式,B的公钥是没办法被中间人替换的,除非CA机构的私钥泄露。。。。。。
证书签发与证书链
证书签发
如果我们有一个网站需要使用https,则需要申请证书,以B为例,申请证书需要两步:
1.生成请求信息
2.生成签名合成证书
通过以上的过程就生成了一个合法的证书,但是真实的情况下,CA不可能随便给每个用户签名的,因为CA的私钥是非常机密,随便签发增加泄露的可能性。既然自己干不了,那就找 “代理商”,进行分级签发证书。
证书链
CA为了减轻自己的工作,同时也是保护私钥的机密,打算招两级代理 A与B(也可以多招几级),A是一级代理,B是二级代理。这个时候C需要生成合法的证书,直接找B即可,每一级的签发流程如下:
反向校验
在上图中,C找到B生成了证书,之前我们知道要验证证书中公钥的合法性,需要去找证书的签发者进行解密校验,同样道理,证书链也是这个流程,只不过是找了多级,C找B,B找A,A找CA。
大家有没有发现最后一级,CA怎么还有证书?谁给他签名呀?
自签名
为了打通整个证书链,CA自身需要有证书,也就是自签名,很好理解,CA必须要信任自己,自签名的证书被称为根证书。
证书链位置
SSL/TLS协议
证书链的存在就是为了解决图5中B的公钥传输可信问题,B其实就是我们的网站(服务端),A是使用的浏览器(客户端)。证书链的位置如图所示:
可能这样看的有点抽象,访问一下知乎,点击地址栏上的锁,会出现证书:
点击证书就可以查看,这就是从知乎网站服务器返回的证书链。
如果你使用wireshark抓包的话,会更加生动地看到传输的证书链:
客户端本地
浏览器内置了一些可信的根证书和中间证书(大代理):
当浏览器获得服务器返回的证书链,需要对证书链进行一级一级地校验,如果校验的证书链的最后一级属于浏览器的可信证书,则建立连接,正常通信,否则会被浏览器标识为不安全,甚至断开通信。
潜在的风险
虽然通过上面的方式,整个方案已经非常完美了,但是依然存在风险,不是方案不安全,而是人不安全。问题就出现在证书链上:
证书链中CA机构的保密性最高,但是他的代理不一定了,只要黑客渗透到他的代理商里,窃取私钥进行签发证书,就可以骗过证书链的检测。(已经发生过)
供应链攻击:比如浏览器被黑客内置了一些自签名的根证书,用户下载恶意的浏览器,通信都是不安全的。其实我们对浏览器或者app进行抓包,也是用了这种方法。
最后
推荐一个自己写的一个抓包工具,代码简短明了,方便大家看到证书的伪造和签名流程。
https://github.com/qiyeboy/BaseProxy
推荐两本同事大佬的书,很厉害:
参考文献
https://www.secrss.com/articles/3298
https://blog.51cto.com/11883699/216003
推荐阅读:
如果大家喜欢这篇文章的话,请不要吝啬分享到朋友圈,并置顶公众号。
关注公众号:七夜安全博客
回复【8】:领取 python神经网络 教程
回复【1】:领取 Python数据分析 教程大礼包
回复【2】:领取 Python Flask 全套教程
回复【3】:领取 某学院 机器学习 教程
回复【4】:领取 爬虫 教程
回复【5】:领取编译原理 教程
回复【6】:领取渗透测试教程
回复【7】:领取人工智能数学基础