用户敏感数据获取
1. 架构概述与参与角色
本流程描述游戏如何通过 SUD OP 安全地获取用户个人信息。根据数据敏感度,分为用户基础信息获取和用户敏感信息获取。
- Game:游戏客户端
- Game SVR:游戏服务端
- SUD OP:向游戏提供登录及用户信息能力的 OpenPaaS 运行环境
- SUD OP SVR:OpenPaaS 服务端,负责用户身份和会话密钥管理
2. 前置条件
- Login 流程已完成:Game 已调用
sud.login()获取临时登录凭证code,Game SVR 已通过code2session换取用户会话信息。
3. 用户基础信息获取(非敏感数据 / 无加密流程)
适用场景:向游戏提供公开、非敏感的基础信息(用户昵称、头像)。此类数据即使在网络传输或客户端被截获,也不会造成核心资产泄漏。 优势:链路极短,无需服务端参与复杂的票据流转与加解密,响应极快。
3.1 获取基础信息交互时序图
3.2 关键步骤说明
- 发起请求:Game 调用
sud.getUserInfo()请求当前用户的基础信息。 - 获取信息:SUD OP 在平台内部完成用户授权状态校验和基础信息获取。
- 返回结果:SUD OP 将
userInfo返回给 Game,流程结束。
如果用户尚未授权,游戏应先通过用户主动操作完成授权,具体方式参见用户信息获取。
4. 用户敏感信息获取(高安全级别 / 完整加密流程)
适用场景:游戏需要获取手机号、真实姓名、平台原始用户标识等敏感信息。
机制:SUD OP 返回经过当前会话 session_key 加密和签名的数据。Game 将加密结果提交给 Game SVR,由 Game SVR 使用登录阶段保存的同一个 session_key 完成验签和解密。
4.1 获取敏感信息交互时序图
4.2 关键步骤说明
- 发起请求:Game 调用
sud.getUserProfile()请求用户敏感信息。 - 平台处理:SUD OP 在内部完成用户授权校验、敏感信息获取、数据加密和签名。
- 返回密文:SUD OP 将
userInfo、rawData、encryptedData、iv和signature返回给 Game。 - 提交服务端:Game 将收到的原始字段提交给 Game SVR,不应在客户端尝试解密。
- 验签解密:Game SVR 使用登录阶段保存的
session_key验证数据完整性并解密encryptedData。 - 使用结果:Game SVR 校验解密结果与当前用户和业务请求一致后,再按业务需要使用或返回数据。
4.3 数据处理约束与算法规范
1. 算法选型基础
| 类别 | 算法 | 说明 |
|---|---|---|
| 数据加密 | AES-128-CBC | 密钥必须是 sessionKey 经过 Base64 解码后得到的 16 字节 byte 数组,配合 16 字节的随机 IV |
| 数据签名 | SHA1 | 使用原文拼接 sessionKey 字符串进行哈希,保障数据传输不被篡改 |
| 填充模式 | PKCS7Padding | 加密块对齐必须使用此填充方式 |
2. 加密机制详细说明
敏感数据绝对不能以明文在网络中传输。SUD OP 返回的数据遵循以下加密规则:
- 当前会话的
sessionKey通常为一个 24 字符的 Base64 字符串。 - 每次加密动态生成一个 16 字节随机 IV,严禁使用固定值。
- 将敏感字段组装为 JSON 字符串,并转换为 UTF-8 byte 数组。
- 将
sessionKey进行 Base64 解码,得到 16 字节 AES 密钥。 - 使用该密钥和 IV,通过
AES-128-CBC/PKCS7Padding对敏感信息进行加密。 - 对密文和 IV 分别进行 Base64 编码,得到
encryptedData和iv。
假设 sessionKey 为 tiihtNczf5v6AKRyjwEUhQ==,敏感信息为:
{"phoneNumber":"13800138000"}Game SVR 解密时需要执行相反的过程:Base64 解码 session_key、iv 和 encryptedData,再使用 AES-128-CBC/PKCS7Padding 还原敏感信息 JSON。
3. 签名机制详细说明
为了确保返回数据未被篡改,平台会对明文数据进行签名:
- 提取返回结果中的
rawData字段。 - 将
rawData与sessionKey直接拼接:rawData + sessionKey。 - 使用 SHA1 算法计算摘要。
- 将摘要转换为小写十六进制字符串,生成最终的
signature。
Game SVR 必须使用收到的原始 rawData 进行验签,不得解析后重新序列化,否则可能因空格、换行或转义字符变化导致验签失败。
4.4 返回参数
| 参数名 | 类型 | 必传 | 说明 |
|---|---|---|---|
| userInfo | UserInfo | 是 | 用户基础信息对象,不包含敏感信息 |
| rawData | string | 是 | 不包括敏感信息的原始数据字符串,用于计算签名 |
| encryptedData | string | 是 | 用户敏感信息经过 AES-128-CBC 加密后生成的 Base64 密文串 |
| iv | string | 是 | AES 加密使用的 16 字节随机 IV 的 Base64 编码字符串 |
| signature | string | 是 | 使用 rawData 拼接 sessionKey 后进行 SHA1 计算得到的十六进制字符串 |
UserInfo 用户信息说明:
| 参数名 | 类型 | 必传 | 说明 |
|---|---|---|---|
| nickname | string | 是 | 用户昵称 |
| avatarUrl | string | 是 | 用户头像 URL |
4.5 返回示例
{
"userInfo": {
"nickname": "张三",
"avatarUrl": "https://res.domain.com/a.png"
},
"rawData": "{\"nickname\":\"张三\",\"avatarUrl\":\"https://res.domain.com/a.png\"}",
"encryptedData": "C6T9Xp7z8L6mQwZkF1vO9/jR4a...[Base64]...",
"iv": "MWEyYjNjNGQ1ZTZmN2c4aA==",
"signature": "1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d"
}5. Game SVR 安全规范与开发避坑指南
5.1 会话密钥只允许保存在服务端
session_key 是解密用户敏感信息的核心凭证,只能保存在 Game SVR。严禁将其写入客户端代码、返回给 Game,或输出到日志、监控标签和错误信息中。
5.2 签名原串必须严格一致
这是联调中最常出现的错误。平台在计算 SHA1 签名时,传入的原文与最终响应报文中的 rawData 字段字节级完全一致,包括空格、换行和双引号转义等。
Game SVR 验签时必须直接使用接口返回的原始 rawData,不得先解析再重新生成 JSON。
5.3 解密流程
Game SVR 应按以下顺序处理敏感信息:
- 根据游戏自定义登录态定位当前用户和对应的
session_key。 - 使用约定的算法验证
signature;验签失败时立即终止处理。 - Base64 解码
session_key,确认解码后长度为 16 字节。 - Base64 解码
iv,确认解码后长度为 16 字节。 - Base64 解码
encryptedData。 - 使用
AES-128-CBC/PKCS7Padding解密敏感信息。 - 解析 JSON,并校验数据与当前用户、当前会话及业务请求一致。
5.4 异常阻断与合规
- 验签或解密失败:立即阻断业务,不得使用或返回任何敏感信息。
- 会话不匹配:不得使用其他用户、其他游戏或历史登录会话的
session_key。 - 最小化原则:只保存和使用当前业务明确需要、且用户已经授权的敏感字段。
- 减少明文下发:若 Game 不需要直接展示敏感信息,Game SVR 应只返回业务处理结果,而不是完整明文。
