ssl连接过程中session复用失败的原因
最近在开发过程中,遇到了一次https访问失败的场景,场景描述:
在chrome浏览器访问我们的https后端时,如果长时间没有更新请求的话,再次刷新该请求将会返回连接失败的错误,必须重启浏览器方能正常访问,在 safri浏览器下不会出现这个问题,chrome浏览器端显示的错误码为ERR_SSL_VERSION_INTERFERENCE,在网上检索该错误的通用解决方法(https://merabheja.com/solved-fix-err_ssl_version_interference-chrome-error/)均无法解决该问题,通过检查后端日志看到,ssh handshake的错误码为336433429,无论是在百度还是谷歌上检索该错误码的结果都非常少,无法提供有效信息,谷歌上有人提过类似问题(https://sourceforge.net/p/asio/mailman/message/26696960/),大概意思是说这个只有在重复使用相同的客户端证书才会出现这种情况,后来在git上找到了类似问题的解法,鉴于这个问题解答方法很少,特记录如下,方便后人。
首先说下错误码的含义:
336433429,错误码的含义是session id context uninitialized
解决方法:
在server端(只需要在server端)设置session id context即可,代码如下
static int context_id = 1;
if (!SSL_CTX_set_session_id_context(ctx->native_handle(), (const unsigned char*)&context_id, sizeof(context_id))) {
LOG_ERROR("SSL set session id context failed");
return false;
}
也就是调用了下openssl的SSL_CTX_set_session_id_context方法,这个方法的介绍如下:
https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_session_id_context.html
为了方便及加深自己的记忆,翻译如下:
SSL_CTX_set_session_id_context
命名
SSL_CTX_set_session_id_context, SSL_set_session_id_context - 设置context,在这个context中session可以被复用(server side only)
语法
#include <openssl/ssl.h>
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
unsigned int sid_ctx_len);
int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
unsigned int sid_ctx_len);
描述
SSL_CTX_set_session_id_context() 为ctx设置了一个context --- sid_ctx,长度为sid_ctx_len,这样的话在sid_ctx中一个session可以被复用
SSL_set_session_id_context() 为ssl对象设置一个context -- sid_ctx,长度为sid_ctx_len,这样的话在sid_ctx中一个session可以被复用
注释
sessions都是从一个确定的context生成的,当使用i2d_SSL_SESSION/d2i_SSL_SESSION来导入导出session是可能的,但是当导入一个从其他context(比如另一个应用)生成的session将可能带来冲突。这样的话,每个应用都必须设置自己的session id context ---- sid_ctx,这是用来区分context,它是被保存在导出的session里吗。sid_ctx可以是任意的给定长度的二进制数据,所以它可以是应用名、主机名或者服务的名字。
这个session id context成为了session的一部分,这个context是由ssl/tls server服务端来设置的,所以这两个api只会在server端有用。openssl 客户端会在复用session的时候检查这个session id context。
sid_ctx的最大长度限制为SSL_MAX_SSL_SESSION_ID_LENGTH。
警告
如果session id context没有在ssl/tls server端设置并且客户端证书被使用了,那么存储的session将不能够被复用,否则将会引发一个fatal error,并且握手将会失败。
当复用session的时候server返回给openssl client返回一个不同的session id context,那么一个error将会触发,握手将会失败。openssl server将总是会返回正确的session id context,这是因为在复用session时候自己检查session id context。
返回值
0表示失败,1表示操作成功
综上,我觉得上面的问题原因是chrome缓存了ssl的session,在刷新过程中复用了这些session,但是服务端没有设置session id context,导致握手失败连接不成功,服务端设置后一切正常了,待确认。。。。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【TBase开源版测评】分布式事务全局一致性
- R语言进阶之主成分分析
- 二胖写参数校验的坎坷之路
- 图像倾斜校正算法的MATLAB实现:图像倾斜角检测及校正
- R语言时间序列数据指数平滑法分析交互式动态可视化
- R语言进阶之图形的合并
- R语言广义线性模型索赔频率预测:过度分散、风险暴露数和树状图可视化
- 还在使用Future轮询获取结果吗?CompletionService快来了解下。
- R语言通过伽玛与对数正态分布假设下的广义线性模型对大额索赔进行评估预测
- R语言精算学:使用链梯法Chain Ladder和泊松定律模拟和预测未来赔款数据
- 微服务[学成在线] day19:分布式事务
- 微服务[学成在线] day20:项目部署与持续集成(DevOps)
- R语言中回归模型预测的不同类型置信区间应用比较分析
- R语言进阶之坐标轴和文本
- R语言广义线性模型(GLM)广义相加模型(GAM):多元平滑回归分析保险投资风险敞口