[collect]图解HTTPS


今天突然想回顾一下HTTPS的相关知识点,但一时发现自己对这个内容还真的不是很清楚,于是去网上找对应的文章看,下面的这篇文章就是一篇图文并茂的讲解,非常细致、易懂:


我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取。所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。

HTTPS简介

HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。具体是如何进行加密,解密,验证的,且看下图:

1. 客户端发起HTTPS请求

用户在浏览器里输入一个https网址,浏览器连接到服务器的443端口。由于客户端(比如这里的浏览器)对一些加解密算法的支持程度不一样,但是在TLS协议传输过程中必须使用同一套加解密算法才能保证数据能够正常的加解密。所以客户端首先要告知服务端,自己支持哪些加密算法,所以客户端需要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。包含支持的协议版本、支持的加密方法、支持的压缩方法等信息

2. 服务端的配置

采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。如果对公钥和私钥不太理解,可以想象成一把钥匙和一把锁,只是全世界只有你一个人有这把钥匙,你可以把锁给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

3. 传送证书

这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。

4. 客户端解析证书

这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随机值。然后用证书对该随机值进行加密。就好像上面说的,把随机值用锁给锁起来,这样除非有钥匙,不然看不到被锁住的内容。

5. 传送加密信息

这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值作为对称加密算法中的主密钥来进行加密解密了。

6. 服务端解密信息

服务端用私钥解密后,得到了客户端传过来的随机值(密钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和密钥通过某种算法混合在一起,这样除非知道密钥,不然无法获取内容,而正好客户端和服务端都知道这个密钥,所以只要加密算法够彪悍,密钥够复杂,数据就够安全。

7. 传输加密后的信息

这部分信息是服务器端用协商好了之后的密钥(那个由客户端生成的随机值)加密后的信息,可以在客户端被还原。

8. 客户端解密信息

客户端用之前生成的密钥解密服务器端传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策,因为数据是被加密过了的。

=EOF=

原文地址:

http://limboy.me/tech/2011/02/19/https-workflow.html [稍有改动]

,

《“[collect]图解HTTPS”》 有 10 条评论

  1. TLS & SSL 快速进阶
    https://www.villainhr.com/page/2016/10/26/TLS%20&%20SSL%20%E5%BF%AB%E9%80%9F%E8%BF%9B%E9%98%B6
    `
    TLS 算法
      sessionkey 用途
    TLS/SLL 过程
    TLS/SSL 中的基本概念
      Forward Secrey
      ALPN
      SNI
    Session Resumption
      Session ID
      Session Ticket
    CA 证书详情
      CA 链式验证
      CA 合法验证
      证书的吊销
        CRL
        OCSP
        OCSP stapling
    TLS/SSL 优化
      设置 session 缓存
      选择合适的 cipher suite
        False Start
      使用 DH 密钥交换
      开启 OCSP Stapling
      开启 HSTS
      使用 SNI
    完整示例
    参考列表
    `

  2. SSL/TLS协议详解(上):密码套件,哈希,加密,密钥交换算法
    https://xz.aliyun.com/t/2526
    https://www.wst.space/ssl-part1-ciphersuite-hashing-encryption/
    https://www.wst.space/ssl-part-2-diffie-hellman-key-exchange/
    `
    SSL/TLS协议详解(上):密码套件,哈希,加密,密钥交换算法
      SSL的历史
      关于密码学的几点注意事项
      哈希
      接下来是加密
      对称密钥加密
        我们可以使用TLS进行对称加密吗
      非对称密钥加密
        我们可以对所有TLS使用非对称加密吗
      密钥交换算法
        了解SSL中的加密类型
        如何解决
        密钥交换算法
        Diffie-Hellman Key Exchange解释
        方案步骤
        Diffie-Hellman密钥交换背后的数学
        Mallory获得秘密钥匙的机会
        我们现在安全吗
        现在怎么办
    `

  3. SSL/TLS CipherSuite 介绍
    https://blog.helong.info//blog/2015/01/23/ssl_tls_ciphersuite_intro/

    Nginx下配置高性能,高安全性的https TLS服务
    https://blog.helong.info//blog/2015/05/09/https-config-optimize-in-nginx/
    `
    nginx下https配置的优化点,主要有:

    session ticket
    session id cache
    ocsp stapling
    http KeepAlive
    ECDHE等ciphersuite优化
    openssl 编译优化
    `
    TLS协议分析 与 现代加密通信协议设计
    https://blog.helong.info//blog/2015/09/07/tls-protocol-analysis-and-crypto-protocol-design/
    `
    本文目标:

    学习鉴赏TLS协议的设计,透彻理解原理和重点细节
    跟进一下密码学应用领域的历史和进展
    整理现代加密通信协议设计的一般思路
    `

  4. TLS安全通信原理
    http://shanks.leanote.com/post/TLS%E7%9B%B8%E5%85%B3
    `
    加密
    * 对称加密
    * 非对称加密
    安全风险
    TLS
    双向认证
    参考资料
    `
    数字签名是什么?
    http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

    HTTPS那些事之SSL证书
    https://zhuanlan.zhihu.com/p/30980579

    证书格式简介及不同格式之间的转换方式
    https://www.cnblogs.com/eshizhan/archive/2012/10/07/2713557.html

    安全:为什么我们必须停止信任12306的根证书
    https://www.landiannews.com/archives/38679.html

    浅谈对称加密与非对称加密
    https://zhuanlan.zhihu.com/p/49494990

  5. 扯一扯HTTPS单向认证、双向认证、抓包原理、反抓包策略
    https://juejin.cn/post/6844903809068564493
    `
    HTTPS在保证数据安全传输上使用对称加密和非对称加密相结合的方式来进行的,简单来说就是通过一次非对称加密算法进行了最终通信密钥的生成、确认和交换,然后在后续的通信过程中使用最终通信密钥进行对称加密通信。之所以不是全程非对称加密,是因为非对称加密的计算量大,影响通信效率。

    为了防止中间人攻击,可以使用SSL-Pinning的技术来反抓包。

    可以发现中间人攻击的要点的伪造了一个假的服务端证书给了客户端,客户端误以为真。解决思路就是,客户端也预置一份服务端的证书,比较一下就知道真假了。

    SSL-pinning有两种方式: 证书锁定(Certificate Pinning) 和公钥锁定( Public Key Pinning)。

    * 证书锁定 – 需要在客户端代码内置仅接受指定域名的证书,而不接受操作系统或浏览器内置的CA根证书对应的任何证书,通过这种授权方式,保障了APP与服务端通信的唯一性和安全性,因此客户端与服务端(例如API网关)之间的通信是可以保证绝对安全。但是CA签发证书都存在有效期问题,缺点是在 证书续期后需要将证书重新内置到APP中。
    * 公钥锁定 – 提取证书中的公钥并内置到客户端中,通过与服务器对比公钥值来验证连接的正确性。制作证书密钥时,公钥在证书的续期前后都可以保持不变(即密钥对不变),所以可以避免证书有效期问题,一般推荐这种做法。
    `
    为了抓包某app,我折腾了10天,原来他是用SSL Pinning防抓包的
    https://juejin.cn/post/6844903809068564493

    用`降维打击`安排安卓 app 的 TLS 双向认证
    https://blog.yii2.cc/mutual-tls-authentication/

    如何突破双向证书认证防护
    https://www.secpulse.com/archives/54027.html

  6. 启用了 https 的网站登录时密码加密有意义吗?
    https://www.v2ex.com/t/854741
    `
    Question:
    今天登录某些网站时发现对密码进行了加密传输,这样做是防止哪些漏洞?

    Answers:
    多一把锁
    ==
    接入国内 CDN 后, 它们是能看到明文的
    =
    不只國內, 國外的 cdn 也能看到明文
    ==
    美国已经有第一岛链了,第二岛链还有意义吗?
    你默认 HTTPS 100%安全,但在安全人员眼里根本不存在 100%的安全。
    心脏滴血就是一个血淋淋的例子,安全防线不可能只有一条。
    ==
    很有意义,HTTPS 未必可信。
    ==
    可能是为了减少整个环节( CDN 、负载均衡器、Web 服务器等)的攻击面,万一日志配置有误也不会造成明文密码泄露,相当于多加了一道保险。毕竟像 github 和 twitter 这种大厂都出现过日志泄露明文密码的漏洞:
    https://www.sohu.com/a/230309592_465914
    https://www.sohu.com/a/230826659_175007

    明文密码泄露会增加用户的其他服务被撞库的风险,比方说有人在 V2EX 用的密码是 Sbkill1rQlb6xv2 ,那么假如泄露了明文密码,撞库攻击者很可能会按照规律(十步杀一人千里不留行+网站名缩写)猜测这个人在 cloudflare 用的密码是 Sbkill1rQlb6xcf
    ==
    有的,IDC 从业者来答一下:很多 SSL offload 之后的流量会在数据中心内部长达数百米到数公里的物理链路中裸奔,而在很多共享 /托管数据中心,保护这些物理链路的只有象征性的机柜围笼、机柜门锁和柜列通道门禁。
    ==
    前端加密靠不住的,执行文件直接可查看,用 md5 或者 sha1 反而不安全(彩虹表暴力破解),加盐也毫无意义,是固定盐的话照着再跑一遍仍然没用,非固定盐就又存在另外一个问题,盐从哪获取?

    如果已知客户端不可信,那么任何手段都无法阻止用户的密码被泄露,这种就需要引入多因子认证,也就和密码加密没关系了。

    https 解决的是 http 传输过程安全性的问题,想要解决客户端不可信的问题只能上硬件方案或者多因素认证,单靠密码是解决不了客户端信任问题的。

    反而前端加密引入了更多的问题
    1.服务端无法验证是否弱密码
    2.服务端无法验证此密码是否已泄露(即其它脱库密码列表中)
    3.服务端无法验证密码格式是否符合强密码要求
    ==
    我可以这样说,如果不能对用户的明文密码保持 zero knowledge ,这个网站大概是打算倒闭后拿用户密码再去其他网站撞一波库。
    ==
    验证是否弱密码不能在前端进行?至于是否已泄露,你去看看哪个查询密码泄露的网站需要提交明文密码的。
    ==
    @GuuJiang hash 之后还可以再次 hash ,不过我说的重点不是这个,而是将原始明文密码发送到后端的不可靠性。
    脱裤后泄露最大的危害是撞库,某个网站自己被脱了他肯定有补救措施,比如强制两步验证、暂停登录等。但其他网站就不行了。只要加盐 hash 至少一次就可以确保 A 站脱的库无法威胁到 A 站以外的其他网站的用户帐户,这才是最关键的。
    另外如果前端将明文密码发送到后端,那这个服务就是不可信的,你没法验证他到底有没有存储明文。除了内鬼泄露、脱裤被拿去撞库以外,很多不使用密码管理器的用户的明文密码中同时 encode 了如生日、名字拼音等隐私信息,可以在社工的时候提供相当的参考。
    ==
    不一定,要看你这个 https 加在哪里,现在一般都有 CDN LB WAF 之类的,如果直接到到你后端服务没问题,但是如果 nginx 等等中间经过的层有日志之类的就存在泄漏用户明文密码的风险。最少前端 Hash 一下后端保存再加盐 Hash 一下。
    ==
    我赞同 @GuuJiang 的观点,前端不要闲得没事自己做哈希,你们是准备把弱密码库之类的也写个 js 库自己前端做校验吗?然后弱密码策略也前端自己维护一份?比如什么密码包含生日包含连续数字包含账户名这种?

    当然如果做加密我不反对,尤其是用非对称的,前端 js 里固定公钥就行,后端可以在注册和登录的时候照常反解回来,然后各种安全服务可以照常调用,弱密码相似密码也都不用前端处理,就是后端高并发的性能会差一些。
    ==
    @zpf124 你再仔细想想。拿到后端 hash 后的结果不等于拿到前端 hash 后的结果。
    前端 hash 和后端 hash 是两个截然不同的安全层。前者的意义在于让后端不能接触到用户的明文密码,对用户的密码保持 zore knowledge 。而后者是阻止本站被脱裤后攻击者登录本站用户的账号。我上面主要强调第一点因为我觉得第一点更重要,因为本网站被拖总是有感知的,有感知就有办法补救。其他网站撞库才是最大的威胁。
    而你们说的好像一但做了第一点就不能再做第二点了,事实上做不做第二点是另一个问题,与第一点没什么关系。
    具体的例子可以去看看 bitwarden 的白皮书。
    ==

    `
    https://bitwarden.com/images/resources/security-white-paper-download.pdf

  7. Should I hash the password before sending it to the server side?
    https://stackoverflow.com/questions/3391242/should-i-hash-the-password-before-sending-it-to-the-server-side
    `
    This is an old question, but I felt the need to provide my opinion on this important matter. There is so much misinformation here

    The OP never mentioned sending the password in clear over HTTP – only HTTPS, yet many seem to be responding to the question of sending a password over HTTP for some reason. That said:

    I believe passwords should never be retained (let alone transmitted) in plain text. That means not kept on disk, or even in memory.

    People responding here seem to think HTTPS is a silver bullet, which it is not. It certainly helps greatly however, and should be used in any authenticated session.

    There is really no need to know what an original password is. All that is required is a reliable way to generate (and reliably re-generate) an authentication “key” based on the original text chosen by the user. In an ideal world this text should immediately generate a “key” by hashing it using irreversible salt. This salt should be unique to the user credential being generated. This “key” will be what your systems use as a password. This way if your systems ever get compromised in the future, these credentials will only ever be useful against your own organisation, and nowhere else where the user has been lazy and used the same password.

    So we have a key. Now we need to clean up any trace of the password on the clients device.

    Next we need to get that key to your systems. You should never transmit a key or password “in the clear”. Not even over HTTPS. HTTPS is not impenetrable. In fact, many organisations can become a trusted MITM – not from an attack perspective, but to perform inspections on the traffic to implement their own security policies. This weakens HTTPS, and it is not the only way it happens (such as redirects to HTTP MITM attacks for example). Never assume it is secure.

    To get around this, we hash the key with a once off nonce. This nonce is unique for every submission of a key to your systems – even for the same credential during the same session if you need to send it multiple times. You can reverse this nonce once it arrives in your own systems to recover the authentication key, and authenticate the request.

    At this point I would irreversibly hash it one last time before it is permanently stored in your own systems. That way you can share the credential’s salt with partner organisations for the purposes of SSO and the like, whilst being able to prove your own organisation cannot impersonate the user. The best part of this approach is you are never sharing anything generated by the user without their authorisation.

    Do more research, as there is more to it than even I have divulged, but if you want to provide true security to your users, I think this method is currently the most complete response here.

    TL;DR:

    Use HTTPS. Securely hash passwords, irreversibly, with a unique salt per password. Do this on the client – do not transmit their actual password. Transmitting the users original password to your servers is never “OK” or “Fine”. Clean up any trace of the original password. Use a nonce regardless of HTTP/HTTPS. It is much more secure on many levels. (Answer to OP).
    将用户的原始密码传输到你的服务器从来就不是“OK”或“Fine”。你应该清除所有原始密码的痕迹。不管HTTP/HTTPS,都使用nonce。它在很多层面上都更安全。
    `

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注