看到这个标题,很多老铁会斩钉截铁的说,这道题我会!就是用https来进行安全传输的。
对,很优秀,那你知道https底层是如何对数据进行安全保障的吗?下面就进入我们今天的主题介绍: https是如何实现数据安全传输的。
https认知
https其实是http + SSL协议组成的安全协议。
我们知道,从我们输入URL到页面呈现的过程是作用于http协议的,http协议保证我们网络传输数据的基础,但是安全性无法保证,而SSL协议作用于Http协议就能解决安全问题。
https保证以下三点:
- 数据内容加密
- 数据完整性保护(数字摘要、数字签名)
- 身份认证
https保证安全性要点:
- 握手阶段:使用
非对称加密技术
对公钥
进行加密 - 传输阶段:使用
对称加密技术
对报文
进行加密
由于https多了一层使用非对称加密算法对公钥进行加密的过程,因此建立连接的时间比http要慢。
握手阶段保证了连接是安全的,那么后续的数据传输就可以安全的进行传输,因此可采用耗时较少的对称加密算法对报文进行加密传输。
https解构
https的架构图在上图中,我们看到SSL协议的作用,在了解保证数据安全的SSL协议之前,我们先了解一些关于数据安全涉及的一些概念。
加解密相关概念
对称加密
别名: 私钥加密、单密钥算法、传统密码算法。
概念:指使用相同的密钥
进行加解密,因此从加密密钥可以推算出解密密
钥,也可以从解密密钥推算出加密密钥。
常见的对称加密算法:DES(Data Encryption Standard)、AES(Advanced Encryption Standard)、RC4、IDEA
非对称加密
别名:公钥加密
概念:公钥是对外公开的,私钥存储在通信两端的各自手里。客户端跟加密的公钥形成一对密钥对, 服务端跟加密的公钥形成另外一对密钥对,加解密的密钥是成对的
限制:加密内容的长度不能超过公钥的长度
数字摘要
别名: 数字指纹
概念: 明文采用单项Hash函数生成的一串固定长度(128位)的密文。
// Hash函数
fucntion Hash (plainText) { // 传入明文参数
// 明文加密过程
const encryptedAbstract = encrypt(plainText)
// 返回固定长度(128位)的数字摘要
return encryptedAbstract
}
数字签名
概念:非对称密钥加密技术和数字摘要的混合应用
数字签名过程
1、发送者使用Hash函数 (H) 将原文生成数字摘要A
2、发送者使用自己的私钥, 对数字摘要A进行加密, 生成密文CypherA
3、将密文CypherA与原文一起传送给接收者
数字签名验证(信息的完整性)过程
1、接收者使用Hash函数 (H) 将接收到的原文生成数字摘要B (B === A, H函数是一样的)
2、接收者使用公钥,对接收到的加密密文 (CypherA) 进行解密, 得到数字摘要B'
3、对比B' 与 B 是否相等, 如果相等,说明收到的信息是完整的并且消息确实是由该发送方签名并发送的(因为私钥只有发送方自己知道),在传输过程中没有被修改;否则信息被修改
最后比较数字摘要A与数字摘要A'是否相等,也可以逆向使用Hash()函数,将摘要A'进行还原得到明文,比较改明文与传过来的原文是否一致(都是pig)。
数字签名
是个加密
的过程,数字签名验证
是个解密
的过程。
一次数字签名涉及到一个哈希函数、接收者的公钥、发送方的私钥。
伪代码
// 单项Hash函数
fucntion Hash (plainText) { // 传入明文参数
// 明文加密过程
const encryptedAbstract = encrypt(plainText)
// 返回固定长度(128位)的数字摘要
return encryptedAbstract
}
// 发送者使用自己的私钥对明文产生的数字摘要进行加密, 生成密文CypherA
function doEncrypt (senderPrivateKey, encryptedAbstract) {
const CypherA = encrypt(senderPrivateKey, encryptedAbstract)
return CypherA
}
// 发送报文
function sendMessage (plainText) {
const encryptedAbstract = Hash(plainText)
const CypherA = doEncrypt(senderPrivateKey, encryptedAbstract) // 加密
return {
CypherText: CypherA,
originText: plainText
}
}
// 接收者用公钥解密
function doDecrypt (publicKey, encryptedAbstract) {
const decryptedAbstract = decrypt(publicKey, encryptedAbstract)
return decryptedAbstract
}
// 接收报文
function receiveMessage (CypherA, plainText) {
const encryptedAbstract = Hash(plainText)
const decryptedAbstract = doDecrypt(publicKey, encryptedAbstract) // 解密
if (decryptedAbstract === encryptedAbstract) {
console.log('1、the sender is true') // 消息发送者的确认
console.log('2、the message is complete') // 消息完整性的确认
}
}
const message = sendMessage(plainText) // 数字签名过程
receiveMessage (message.CypherText, message.originText) // 数字签名认证过程
数字证书
在上述数字签名的过程中,我们如何保证这个公钥是可信任的?这就是数字证书存在的必要性。
数字证书主要用于加密、签名、身份认证。
数字证书由证书颁发机构(CA, Certification Agent)
颁发, CA会在颁发证书之前以及使用证书时对持有者的身份进行验证,它让客户端有能力去识别公钥是否来自合法的服务器。
证书颁发机构(CA)
颁发包含公钥和所有者身份的数字证书。匹配的私钥不是公开的,而是由生成密钥对的最终用户保密。证书还是CA的确认或验证,证书中包含的公钥属于证书中标注的个人,组织,服务器或其他实体。CA在此类方案中的义务是验证申请人的凭证,以便用户和信赖方可以信任CA证书中的信息。
当您访问使用 HTTPS(安全连接)的网站时,该网站的服务器会使用证书向浏览器(如 Chrome)证明该网站的身份。
证书中包含的公钥信息是可信任的, 如果证书不存在、证书被篡改、证书失效等情况,浏览器会在左上角提示你该网站不安全。
签名验证链条:client <- 服务器 <- CA
数字证书的内容
- 证书颁发机构的名称
- 证书本身的数字签名
- 证书持有者公钥
- 证书签名用到的Hash算法
-
...等等
image.png
公钥和数字签名
image.png
了解这些基本概念后, 进入我们今天的主题: SSL协议
SSL/TLS
其实是一种协议,不同的叫法。
SSL(Secure Socket Layer, 安全套接字层)
利用加密技术,确保数据在网络传输过程中不会被窃取。
SSL/TLS
TLS (Transport Layer Security,传输层安全协议)
用于两个应用程序之间提供保密性和数据完整性。
该协议建立在SSL3.0协议的基础之上,可理解为SSL3.1版本。只不过在SSL3.0的基础上采用了一些更安全的策略,让数据更加安全,其他的协议分层与功能与SSL一致。有兴趣的可自行了解其与SSL的区别与优势。
SSL/TLS协议的作用:
- 数据加密,防止被窃取
- 保护数据的完整性,确保数据不会被改变
- 身份认证,确保数据被发送到正确的客户端和服务器
可以看到, 这正是https协议发挥作用的三点。
那么, SSL协议到底是如何把我们数据进行加密,从而进行安全传输的呢?
SSL、TLS的握手过程
SSL握手过程1、客户端告知服务端自己支持的安全协议版本(如TLS1.0)
、加密算法
、压缩方法
、随机数CRandom1
;
2、服务端首次响应,返回给客户端安全协议的版本
、加密算法
、压缩方法
、随机数SRandom
, 还有一个数字证书(服务器证书)
;
3、客户端对服务端发送过来的证书进行验证("如何进行验证的?"),验证通过后,进行如下操作:
- 客户端再次产生一个随机数CRandom2
- 使用服务器证书中的公钥对数据进行进行加密,生成随机数CRandom3
- 发送
ChangeCipherSpec(编码改变)的消息通知(告知服务器我已经准备好用我们之前商量好的加密套件进行加密并传输数据了)
、前面所有消息的hash值
以及加密数据CRandom3
进行服务器验证 - 使用与服务器确认的加密算法对CRandom1、CRandom2、CRandom3三个随机数进行加密,生成Session Secret(这个就是后边使用对称加密算法进行传输数据时所用到的对称加密密钥,还可用来
会话恢复
, 节约SSL的握手时间)
4、服务器再次响应:
- 使用自己的私钥对CRandom3进行解密、并对解密后的数据进行验证
- 发送
ChangeCipherSpec(编码改变)的消息通知(告知客户端我也准备好了用我们之前商量好的加密套件和Session Secret进行加密数据了)
- 使用Session Secret加密一段Finish的消息发送给客户端, 以验证之前通过握手建立起来的加解密通道是否成功
到上面四步,客户端与服务器已经确定了密钥,就可以对消息进行加密传输了。
到此,握手过程结束。
整个握手阶段的安全,取决于第三个随机数CRandom3能否被破解,因为这个随机数是使用服务端的公钥进行加密的、服务端的私钥进行解密的;而私钥只存储在了服务端本身。
在所有的握手阶段都完成之后,就可以使用对称加密技术开始传送应用数据了。
总结
网络安全传输数据依赖SSL协议,而网络传输的协议是HTTP, 因此构成了HTTPS协议。而HTTPS要保证客户端与服务器端的高效通信安全,必须使用对称加密算法,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,然而直接使用非对称加密的过程本身也不安全,会有中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构颁发的证书来保证非对称加密过程本身的安全。这样通过这些机制协商出一个对称加密算法,就此双方使用该算法对数据进行加密解密传输,从而解决了客户端与服务器端之间的通信安全问题。
思考
1、客户端如何对接收到的证书进行验证的?
证书本身就已经告诉客户端怎么验证证书的真伪。
也就是证书上写着如何根据证书的内容生成证书编号。客户端拿到证书后根据证书上的方法自己生成一个证书编号,如果生成的证书编号与证书上的证书编号相同,那么说明这个证书是真实的。
2、公钥的安全性是通过证书来确认的, 但是证书是由颁发机构来颁发的, 那如何确认这个办法者是可信的呢?
通过证书链。
证书链
-
root:根证书,权威证书认证机构(CA, Certificate Authority)给自己颁发的数字证书,也就是自己认证自己。在上图中根证书就是由DigiCert Global Root CA自己给自己签发的。
-
intermediates:中间证书,根CA生成一对公钥、私钥,并用私钥将中间CA的信息和公钥进行“加密”生成签名,封装得到中间证书。需要注意的是,中间CA可能不止一个。上一级CA同样按照这个逻辑给下一级CA进行签发证书。在这里中间CA就是RapidSSL RSA CA 2018,它给末端使用者签发证书。
-
end-user:末端使用者(证书)。图中的末端证书就是*.juejin.im使用的数字证书。
可以看到证书链由多个证书一层一层组成的。
末端证书的公钥是给用户加密报文外,其他层证书中的公钥均用于解密下一层的证书指纹签名。
最高层的根证书是自签名的,也就是自己颁发给自己,所以根证书一定是可信的
(难道自己还不能信任自己吗?^^)
笔者简单带大家了解了数据安全传输的关键点, 其实关于安全的话题还有很多值得深入的点,欢迎大家给我留言~共同学习,共同进步。创作不易,如果本文对你有那么一点点帮助的话, 点个赞送我上热搜(#.#),让我有更多的动力继续创作~
网友评论