HTTPS加密流程以及抓包原理解析

一.HTTPS SSL/TLS

HTTPS通过SSL/TLS协议实现安全通信,其核心在于握手阶段的加密协商和密钥交换,随后使用对称加密传输数据。以下是详细的流程和加密原理:

image-20250326225133574


TLS1.2 密钥协商流程

  1. ClientHello

    • 客户端向服务器发送支持的TLS版本、可用加密套件列表(如TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)及一个客户端随机数(Client Random)。
  2. ServerHello

    • 服务器选择TLS版本、加密套件,并生成服务器随机数(Server Random),返回给客户端。
  3. 证书与密钥交换参数

    • 证书传输:服务器发送数字证书(包含公钥和CA签名),客户端验证证书的合法性(CA信任链、有效期、域名匹配等)。

    • ServerKeyExchange(可选):若使用ECDHE等算法,服务器发送临时公钥参数(如椭圆曲线参数)和签名,确保参数未被篡改。

    • ServerHelloDone:通知客户端初始握手信息发送完毕。

  4. 客户端密钥交换

    • 验证证书:客户端验证服务器证书后,生成预主密钥(Pre-Master Secret)。
      • RSA密钥交换:客户端用服务器公钥加密预主密钥并发送。
      • ECDHE密钥交换:客户端生成临时DH参数,发送给服务器;双方通过ECDH算法计算共享密钥作为预主密钥。
    • 发送ClientKeyExchange消息(包含密钥参数)。
  5. 生成会话密钥

    • 双方使用预主密钥Client RandomServer Random,通过伪随机函数(PRF)生成主密钥(Master Secret)。
    • 主密钥进一步派生成会话密钥(对称加密密钥、MAC密钥、初始化向量IV等)。
  6. 切换加密模式

    • 客户端和服务器分别发送ChangeCipherSpec,确认后续通信使用协商的密钥加密。
    • 发送Finished消息(加密的握手消息摘要),验证密钥和握手过程完整性。
  7. 应用数据传输

    • 握手完成,后续数据使用对称加密(如AES)和MAC(或AEAD模式如GCM)进行加密传输。

TLS 1.3 密钥协商流程

一、TLS 1.3 握手流程(1-RTT模式)

1. ClientHello(客户端发起握手)

  • 关键内容
    • 支持的TLS版本:显式声明支持TLS 1.3。
    • 密钥交换参数:通过 key_share 扩展携带客户端临时公钥(如X25519、secp256r1)。
    • 加密套件列表:仅支持前向保密算法(如TLS_AES_128_GCM_SHA256)。
    • 随机数:生成32字节客户端随机数(Client Random)。
    • SNI扩展:指明目标域名(如x.secself.com)。
    • 其他扩展supported_versionssignature_algorithms等。

image-20250327011013556

2. ServerHello(服务器响应)

  • 关键内容
    • 选定协议版本:通过 supported_versions 扩展确认使用TLS 1.3。
    • 密钥交换参数:通过 key_share 扩展返回服务器临时公钥。
    • 随机数:生成32字节服务器随机数(Server Random)。
    • 选定的加密套件:如TLS_AES_256_GCM_SHA384
    • 证书:服务器证书(含公钥),可能包含OCSP装订(证书状态信息)。
    • 签名:对握手消息的签名(使用证书私钥),验证服务器身份。
  • Server Hello

image-20250327011144349

  • 证书

image-20250327003711052

  • 签名信息

image-20250327004004420

3. 密钥计算(客户端与服务器各自完成)

  • 共享密钥计算
    客户端和服务器通过 key_share 中的临时公钥,基于 ECDH算法 计算共享密钥(Shared Secret)。
  • 密钥派生
    • 使用HKDF(HMAC-based Key Derivation Function)从共享密钥派生出:
      • 主密钥(Master Secret):结合Client Random和Server Random生成。
      • 会话密钥:包括:
        • 客户端写密钥(Client Write Key)
        • 服务器写密钥(Server Write Key)
        • 初始化向量(IV)
        • MAC密钥(若未使用AEAD模式)。

4. 完成握手(Finished)

  • 客户端发送Finished
    • 使用会话密钥加密,包含握手消息的哈希值(验证完整性)。

image-20250327004959051

  • 服务器发送Finished
    • 同样加密并验证哈希值。

image-20250327005107018

  • 握手完成:双方开始加密传输应用数据。
    • 使用协商后的生成的会话密钥将HTTP请求加密传输。

image-20250327005403526


加密原理

  1. 非对称加密与对称加密结合

    • 密钥交换:使用非对称加密(如RSA、ECDHE)安全交换预主密钥。
    • 数据传输:使用对称加密(如AES、ChaCha20)高效加密数据。
  2. 前向保密(Perfect Forward Secrecy, PFS)

    • 通过ECDHE等临时密钥交换算法,每次会话生成独立的预主密钥。即使服务器私钥泄露,历史会话仍安全。
  3. 证书与身份验证

    • 服务器证书由可信CA签发,客户端验证其真实性,防止中间人攻击。证书包含服务器公钥,用于签名或加密预主密钥。
  4. 密钥派生与随机性

    • 预主密钥与两个随机数(Client/Server Random)确保每次会话密钥唯一,防止重放攻击。
    • 主密钥通过PRF/HKDF派生成会话密钥,保障密钥分层安全。
  5. 完整性校验

    • 使用HMAC或AEAD模式(如GCM)确保数据未被篡改。
    • Finished消息验证握手过程完整性。

核心优势

  • 效率:对称加密处理数据,非对称加密保护密钥交换。
  • 安全性:前向保密、证书验证、随机数参与密钥生成,抵御多种攻击(如中间人、重放)。
  • 兼容性:支持多种加密套件,适应不同安全需求。

总结

SSL/TLS通过握手协商建立安全通道,结合非对称加密的密钥交换与对称加密的高效传输,辅以证书验证和哈希完整性校验,为HTTPS提供端到端的安全保障。TLS 1.3进一步简化流程并增强安全性,但核心原理保持一致。

单向认证和双向认证是SSL/TLS协议中两种不同的身份验证机制,其核心区别在于是否要求客户端向服务器证明身份。以下是它们的含义及绕过抓包的方法分析:


二.单向认证和双向认证的绕过抓包

1. 单向认证(Server Authentication)

含义

  • 服务器向客户端提供证书,客户端验证服务器身份,但服务器不验证客户端身份。
  • 典型场景:普通HTTPS网站(如访问百度、淘宝)。

验证流程

  1. 客户端验证服务器证书的合法性(CA签名、域名匹配、有效期等)。
  2. 服务器无需验证客户端证书。

如何绕过抓包

  • 中间人攻击(MITM)
    • 工具:使用Burp Suite、Charles、Fiddler等抓包工具。
    • 步骤
      1. 在客户端安装抓包工具的CA根证书(信任该证书)。
      2. 工具作为代理拦截请求,伪造服务器证书(由工具CA签发)。
      3. 客户端信任工具的CA证书,误以为连接到合法服务器。
      4. 工具解密流量后重新加密转发到真实服务器。
    • 关键点:客户端必须信任抓包工具的CA证书。

2. 双向认证(Mutual Authentication)

含义

  • 客户端和服务器均需验证对方身份
  • 服务器要求客户端提供证书,并验证其合法性。
  • 典型场景:银行系统、企业内网API、高安全要求的App。

验证流程

  1. 客户端验证服务器证书。
  2. 服务器要求客户端发送证书,并验证其合法性(如是否由指定CA签发、是否被吊销)。

绕过抓包的难点

  • 客户端证书保护
    • 客户端证书通常与私钥绑定,且私钥可能被加密存储或硬编码在代码中。
    • 服务器只信任特定CA签发的客户端证书(如私有CA)。

3. 绕过双向认证的方法

方法1:获取客户端证书和私钥

  • 适用场景:客户端证书和私钥可提取(如企业内部分发证书)。
  • 步骤
    1. 提取证书和私钥
      • 从客户端安装包、文件系统或钥匙串(如Android的.p12文件、iOS的Keychain)。
      • 使用逆向工具(如Apktool、Frida)从代码中提取硬编码的证书。
    2. 配置抓包工具
      • 在Burp Suite或Charles中导入客户端证书和私钥。
      • 工具在握手时使用客户端证书响应服务器验证。
    3. 正常抓包:工具解密双向认证的流量。

方法2:禁用客户端证书验证(需修改客户端)

  • 适用场景:可控制客户端代码(如测试环境)。
  • 步骤
    1. Hook SSL/TLS库
      • 使用Frida/Xposed(Android)或Cycript(iOS)修改SSL上下文,跳过客户端证书验证。
      • 示例代码(Android Hook):
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        // 使用Frida Hook SSLContext.init方法
        Java.perform(function() {
        let SSLContext = Java.use("javax.net.ssl.SSLContext");
        SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom').implementation = function(kms, tms, sr) {
        // 替换TrustManager为信任所有证书
        let TrustAllManager = Java.registerClass({
        name: 'com.example.TrustAllManager',
        implements: [Java.use('javax.net.ssl.X509TrustManager')],
        methods: {
        checkClientTrusted: function() {},
        checkServerTrusted: function() {},
        getAcceptedIssuers: function() { return []; }
        }
        });
        this.init(kms, [TrustAllManager.$new()], sr);
        };
        });
    2. 绕过证书绑定(Certificate Pinning)
      • 若客户端绑定了服务器证书,需同时绕过证书绑定(如使用Objection、SSLUnpinning)。

方法3:欺骗服务器信任抓包工具的CA

  • 适用场景:控制服务器或内网环境。
  • 步骤
    1. 在服务器端导入抓包工具的CA证书,使其信任该CA。
    2. 工具伪造客户端证书(由工具CA签发),服务器误认为合法。

4. 注意事项

  1. 法律与道德
    • 绕过认证可能违反法律或服务条款,需确保在授权范围内操作(如企业内部分析、安全测试)。
  2. 技术限制
    • 客户端证书可能被硬件保护(如HSM、TEE),无法直接提取。
    • 部分应用使用双向认证+证书绑定(Pinning),需同时绕过多道防护。
  3. 防护建议(开发者视角):
    • 对客户端证书进行代码混淆、加密存储。
    • 启用证书绑定(Certificate Pinning)。
    • 监控异常证书使用行为。

总结

  • 单向认证:通过信任抓包工具的CA证书即可绕过。
  • 双向认证:需获取客户端证书或修改客户端逻辑,技术门槛较高。
  • 核心思路:中间人攻击+证书欺骗,但对客户端或服务器的控制权限要求不同。

三.Wireshark抓取HTTPS包

  • 由于部分软件可以遵循系统配置的环境变量,自动导出预主密钥,到配置的环境变量的文件中,这时就可以将该预主密钥导入到,wireshark中,wireshark就可以解密TLS的包了。
  1. 配置环境变量:变量名:SSLKEYLOGFILE,变量值为任意文件地址即可,例如C:\Users\User\Documents\SSLKEYLOGFILE\SSLKEYLOGFILE.log,可以没有这个文件,系统会自动创建。
  2. 打开chrom游览器,访问任意HTTPS网站,系统就会自动在SSLKEYLOGFILE.log文件中写入预主密钥。
  3. 将该文件导入到wireshark。编辑->首选项->Protocols->TLS,选择预主密钥文件位置,点击应用确定。

image-20250326232642662

  1. 通过过滤器过滤后,找到想要抓包的网站,查询,就可以看到明文数据了。
  • 在没导入密钥之前可以看到,该条No.2098数据显示的协议是TLSv1.3,且数据内容中看不到HTTP协议相关的数据。

image-20250326233128323

  • 在导入密钥后,我可以看到该条数据的协议已经变成HTTP协议了,也能看到HTTP协议的请求头之类的字段了。

image-20250326232804871

  • (至于为什么导入密钥之前看到的是TLS协议,导入之后看到的是HTTP协议,其实很简单。因为TLS是传输层加密协议,是比HTTP更底层的协议,我们在解开TLS里封装的内容之前,我们并不知道里面封装了什么内容,因此只能显示TLS协议)