当前位置: 首页 > news >正文

Android + Kotlin + OkHttp WebSocket 相关概念与使用流程笔记(TLS/证书 + 鉴权/会话)

Android + Kotlin + OkHttp WebSocket 相关概念与使用流程笔记(TLS/证书 + 鉴权/会话)

1. 两大块问题分别解决什么

  • TLS/SSL 相关(SSLContext、SSLSocketFactory、TrustManager 等)
    • 解决:建立加密通道、防篡改、校验“服务器身份可信”
    • 对应协议:HTTPS / WSS(WebSocket over TLS)
  • 鉴权/会话相关(token、cookie、session)
    • 解决:校验“客户端是谁、有没有权限”
    • 主要发生在:WebSocket 的 HTTP Upgrade 握手阶段(因为握手本质是 HTTP)

2. TLS/SSL 相关概念

2.1 TLS/SSL 是什么

  • TLS 是位于 TCP 之上的安全层:加密 + 完整性校验 + 身份认证(主要认证服务器)
  • wss:// = 在 TLS 通道里跑 WebSocket(等价于 https:// 的安全要求)

2.2 SSLContext

  • 概念:TLS 协议栈的“配置入口/上下文”
  • 作用:把信任规则(TrustManager)、客户端证书(KeyManager,可选)等初始化进去
  • 结果:可以从它拿到用于建连的 SSLSocketFactory
  • 典型关系:SSLContext.init(...) -> sslContext.socketFactory

2.3 SSLSocketFactory

  • 概念:创建 TLS Socket 的工厂
  • 作用:OkHttp 建立 https/wss 连接时用于创建底层加密 socket
  • 通常来源:sslContext.socketFactory

2.4 TrustManager

  • 概念:TLS 握手过程中负责“信不信对方证书”的组件
  • 作用:验证服务端发来的证书链是否可信(是否能链到受信任根、是否过期、用途等)

2.5 X509TrustManager

  • 概念:TrustManager 的常用实现,专门验证 X.509 证书链(HTTPS/WSS 常见体系)
  • 注意:所谓“信任所有证书”的实现是高危做法,生产环境不应使用

2.6 TrustManagerFactory

  • 概念:根据一份信任库(trust store)生成 TrustManager 的工厂
  • 作用:你想用系统默认 CA,或额外信任公司内网 CA/自签证书,都会经过它
  • 常见初始化方式:
    • tmf.init(null):使用系统默认信任库
    • tmf.init(keyStore):使用你自定义的 KeyStore 作为信任库

2.7 KeyStore(与上面强相关)

  • 概念:证书/密钥的容器
  • 两种典型用途:
    • 作为“信任库”:放 CA 证书,提供给 TrustManagerFactory 生成 X509TrustManager
    • 作为“客户端证书库”:放客户端私钥+证书,提供给 KeyManagerFactory(用于双向 TLS / mTLS)

2.8 HostnameVerifier(非常关键)

  • 概念:主机名校验器,校验证书里的域名是否匹配你访问的域名
  • 与 TrustManager 的分工:
    • TrustManager:证书链可信不可信
    • HostnameVerifier:证书是不是“发给 api.example.com 的”

3. TLS 建连流程(以 wss:// 为例,OkHttp/Android 视角)

  1. 建立 TCP 连接
  2. 开始 TLS 握手(协商 TLS 版本/加密套件)
  3. 服务器发送证书链(server certificate chain)
  4. 校验阶段:
    • X509TrustManager 校验证书链可信性(是否链到受信 CA、是否过期等)
    • HostnameVerifier 校验域名匹配(证书是否对应该域名)
  5. TLS 握手成功后,得到加密通道
  6. 在加密通道内发送 HTTP 请求进行 WebSocket Upgrade
  7. Upgrade 成功后进入 WebSocket 帧通信(所有帧都在 TLS 加密通道内传输)

什么时候需要自定义 SSLContext/TrustManager?

  • 连接自签证书、公司内网 CA、或证书链不被系统信任的服务时
  • 正确方向:把 CA/证书放进 KeyStore -> TrustManagerFactory 生成 X509TrustManager -> 配到 OkHttp
  • 概念:服务端通过 Set-Cookie 下发、客户端保存并在后续请求中携带的小段键值信息
  • 常见用途:承载 sessionId(例如 JSESSIONID)
  • 特点:
    • 浏览器会自动管理;App 需要 CookieJar 才能自动持久化/携带
    • 有域、路径、过期、Secure、HttpOnly 等属性

4.2 Session

  • 概念:通常指服务端保存的一份“会话状态/登录态”
  • 典型模式:服务端存 session,客户端用 cookie 带 sessionId 来索引 session
  • 特点:状态在服务端,扩容时要考虑共享(如 Redis)或粘性会话

4.3 Token

  • 概念:客户端持有的访问凭证字符串,服务端用它验证身份与权限
  • 常见传递方式:Authorization: Bearer
  • 常见形式:
    • 随机字符串 token:服务端存储并校验
    • JWT:token 自包含 claims 并签名,服务端可不存储(但常需要黑名单/刷新策略)
  • 特点:更易无状态化与水平扩展;需要处理过期与刷新(refresh token)

5. 鉴权在 WebSocket 中的使用流程(因为握手是 HTTP)

5.1 使用 Token 鉴权(最常见)

  1. App 通过登录接口获得 token
  2. 发起 WebSocket 连接时,在握手 HTTP Header 中携带:
    • Authorization: Bearer
  3. 服务端校验 token:
    • 通过:返回 101 Switching Protocols,升级成功
    • 失败:返回 401/403 或拒绝升级
  4. token 过期处理常见策略:
    • 服务端断开连接(close code / reason)
    • 客户端刷新 token 后重新 newWebSocket 重连
  1. 登录响应中服务端下发 Set-Cookie: sessionId=...
  2. 客户端保存 cookie(OkHttp 需要 CookieJar 才能自动带 cookie)
  3. WebSocket 握手时 HTTP 请求会携带 Cookie: sessionId=...
  4. 服务端通过 sessionId 查 session 决定是否允许升级

5.3 连接建立后再发送“鉴权消息”(业务协议选择)

  1. 握手允许匿名升级(或只做弱校验)
  2. WebSocket 建立后第一条消息发送 auth 包(例如 token)
  3. 服务端确认后才允许订阅/下发数据
    说明:这是业务协议做法,不是 WebSocket 标准强制

6. 记忆主线

  • TLS/SSL(SSLContext / SSLSocketFactory / TrustManager):解决“通道安全 + 服务器可信”
  • token/cookie/session:解决“你是谁 + 你能做什么”
  • 对 wss:先 TLS 成功 -> 再 HTTP Upgrade -> 然后才是 WebSocket 消息帧

7. 名词关系速查(从配置到连接)

  • TrustManagerFactory -> 生成 X509TrustManager(信任规则)
  • SSLContext.init(trustManagers, keyManagers?) -> 得到 SSLContext
  • SSLContext.socketFactory -> SSLSocketFactory(用来创建 TLS socket)
  • HostnameVerifier -> 校验域名匹配
  • OkHttp 使用上述组件 -> 建立 HTTPS/WSS -> 发送 WebSocket Upgrade 握手
// 仅示意名词关系(非完整可运行代码)
val sslContext = javax.net.ssl.SSLContext.getInstance("TLS")
// sslContext.init(keyManagers, trustManagers, SecureRandom) 之后:
val sslSocketFactory = sslContext.socketFactory
// OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, x509TrustManager)
http://www.jsqmd.com/news/713664/

相关文章:

  • 游戏资源编辑终极指南:用ExtractorSharp轻松制作个性化DNF补丁
  • 家里闲置的沃尔玛购物卡,别让它白白过期浪费了 - 团团收购物卡回收
  • ThinkPad终极散热优化指南:双风扇智能控制完全教程
  • #2026最新食堂承包公司推荐!广东优质权威榜单发布,口碑靠谱广州等地公司值得选择 - 十大品牌榜
  • 别再只会用MCU了!用FPGA驱动SHT30/SHT35温湿度传感器,I2C时序手把手解析
  • 2026最新牛仔面料批发公司/厂商/定制厂家推荐!国内优质权威榜单发布,广东佛山等地品质靠谱值得选择 - 十大品牌榜
  • 嵌入式/RTOS开发者的福音:手把手教你给FreeRTOS任务代码上覆盖率(解决GCOV环境变量和异常退出问题)
  • 3分钟搭建终极OBS RTSP服务器:obs-rtspserver插件完整指南
  • Kotlin标准库函数takeIf/takeUnless避坑指南:小心空指针和性能陷阱
  • 分析全国金属缠绕垫片专业制造商,哪家口碑好值得推荐? - 工业品牌热点
  • 上班族闲置京东 E 卡别浪费!企业京东E卡快速回收方法 - 喵权益卡劵助手
  • 手把手教你用场景库和仿真,搞定SOTIF标准里的‘未知不安全场景’验证
  • 博客园 MCP 服务发布:让你的 AI 助手直接帮你发博客!
  • 3分钟快速上手:免费开源暗黑破坏神2存档编辑器d2s-editor完全指南
  • 全国好用的房地产纠纷律师怎么选,哪家性价比高 - 工业品牌热点
  • MCP协议对接全解析,手把手带你绕过官方文档盲区实现秒级接入
  • 告别滚动条!用Qt的QTableView实现完美自适应表格(附完整C++源码)
  • #2026需要加上佛山市南海区最新小龙虾小酒馆推荐!佛山优质权威榜单发布,口碑靠谱南海等地小酒馆推荐 - 十大品牌榜
  • 深入RK3568的TrustZone世界:GIC中断如何守护TEE与REE的安全边界?
  • # 【拾零】0 - 开箱即用的现代风终端 |Ghostty + Fish + Starship + fzf + zoxide + Raycast
  • 当AI编程助手对你说“试用已结束“:一个开源工具如何让创意继续流动
  • 别再只盯着颜色了!拆解一根USB2.0数据线,手把手教你从线序到PCB布局的完整设计要点
  • CentOS 7下Qt 5.14.2保姆级安装教程:从.run包到菜单栏图标(含libGL报错解决)
  • 收藏!小白程序员必看:如何构建可持续运行的大模型Agent系统?
  • 2026年生物质与生物基材料优选厂家推荐 - 深度智识库
  • 基于Simulink的偏移鲁棒性无线充电自适应频率跟踪
  • 百联 OK 卡盘活指南:闲置卡券高效变现的实用方法 - 团团收购物卡回收
  • Zotero文献库去重难题:如何用智能合并插件高效清理重复条目?
  • 一键下载B站CC字幕:BiliBiliCCSubtitle工具的3步高效解决方案
  • PyQt5实战:当QGraphicsView遇上图像标注——手把手教你实现一个简易的图片标注工具原型