You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从OpenSSL的SSL会话中提取会话密钥及相关参数

OpenSSL TLS 会话密钥类参数提取方案

握手完成(SSL_accept()/SSL_connect()返回成功)且持有有效SSL句柄时,你需要的所有参数都可以通过OpenSSL提供的能力获取,具体方式如下:

  • master key(主密钥)
    直接调用SSL_SESSION_get_master_key接口即可获取,你代码里注释的调用逻辑是对的,注意主密钥是二进制数据,不能直接用%s格式化打印,需要逐字节转十六进制输出。参考调用代码:
    SSL_SESSION *sess = SSL_get_session(ssl);
    unsigned char master_key[128] = {0};
    size_t mk_len = SSL_SESSION_get_master_key(sess, master_key, sizeof(master_key));
    
    TLS1.2及更早版本主密钥固定为48字节,TLS1.3主密钥长度根据协商的密码套件存在差异,可以先给第二个参数传NULL拿到实际长度后再分配缓冲区。
  • client random、server random(客户端/服务端随机数)
    两个随机数长度均为32字节,直接调用OpenSSL对外暴露的专用接口即可获取:
    unsigned char client_random[32] = {0};
    unsigned char server_random[32] = {0};
    SSL_get_client_random(ssl, client_random, sizeof(client_random));
    SSL_get_server_random(ssl, server_random, sizeof(server_random));
    
  • client write key、server write key(客户端/服务端写密钥)
    OpenSSL没有对外暴露直接获取这两个工作密钥的公开API,有两种可行实现路径:
    • 自行按协议规范计算:拿到前述主密钥、两端随机数后,按照当前连接协商的TLS版本对应的PRF(伪随机函数)规则,自行扩展计算出两端的写密钥、IV、MAC校验密钥。TLS1.2的PRF规则对应标准文档RFC5246,TLS1.3对应RFC8446。
    • 注册信息回调抓取:通过SSL_CTX_set_info_callback给SSL上下文注册握手过程回调,在密钥派生完成的回调事件触发时,直接从SSL连接的内部安全参数结构体中读取已经计算完成的写密钥。这种方式不需要自行实现PRF逻辑,适配所有TLS版本,注意不同OpenSSL大版本的内部结构体成员偏移有差异,生产环境使用需要做版本兼容判断。

场景适配提示

针对你需要解密原始报文做畸形包检测的需求,有两个更简便的实现方式,不需要手动提取密钥后自行解密:

  1. 调用SSL_set_msg_callback接口注册报文回调,OpenSSL会在处理每个TLS报文(包括握手报文、应用数据报文)时,把明文载荷直接传入回调函数,不需要你从socket端口读取原始密文再解密。
  2. 如果必须从socket层抓包解密,注意TLS1.3支持连接中途密钥更新,一旦触发密钥更新,之前拿到的写密钥会失效,需要同步捕获密钥更新事件重新获取新密钥,否则后续报文无法正常解密。

内容的提问来源于stack exchange,提问作者user1897937

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:39:15