You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
10 KiB
10 KiB
Virgil Security 接入到聊天系统设计方案(服务器)
1. 服务器设计目标
服务端的目标不是参与解密,而是提供 业务承载层:
- 业务身份认证
- 设备管理
- Virgil JWT 签发
- 单聊/群聊会话管理
- 密文消息接入与路由
- 离线同步
- 文件上传/下载票据
- 群成员关系与群密钥版本索引
- 风控与设备吊销
2. 服务器总体架构
flowchart LR
subgraph Backend["业务服务端"]
B1["API Gateway"]
B2["Auth Service"]
B3["Virgil JWT Service"]
B4["Conversation Service"]
B5["Message Router / Sync"]
B6["Group Service"]
B7["Push Service"]
B8["File Ticket Service"]
B9["Risk / Device Service"]
B10["Metadata DB"]
end
subgraph Virgil["Virgil Cloud"]
V1["Cards / Public Key Directory"]
V2["Restore Related Services"]
end
subgraph OSS["Object Storage / CDN"]
O1["Encrypted File Objects"]
end
B1 --> B2
B1 --> B3
B1 --> B4
B1 --> B5
B1 --> B6
B1 --> B8
B1 --> B9
B2 --> B10
B3 --> B10
B4 --> B10
B5 --> B10
B6 --> B10
B8 --> O1
B9 --> B10
B3 --> V1
B3 --> V2
3. 服务器职责边界
3.1 服务端应该负责什么
- 用户登录与 token
- 设备注册与吊销
- Virgil JWT 签发
- 会话与群组元数据
- 密文消息存储
- 消息序列号与游标
- 离线消息投递
- 已读/已送达状态
- 文件票据
- 群成员变更事件
- 风控控制
3.2 服务端不应该负责什么
- 私钥保存
- 文本明文解析
- 文件明文解析
- 群密钥管理的明文操作
- 替客户端做消息加解密
4. 推荐服务拆分
api-gateway
auth-service
virgil-jwt-service
conversation-service
message-service
group-service
sync-service
push-service
file-ticket-service
risk-device-service
各服务说明
api-gateway
- 统一入口
- 鉴权
- 请求限流
- trace 注入
auth-service
- 登录
- refresh
- logout
virgil-jwt-service
- 生成 Virgil JWT
- user/device 到 virgil identity 的映射
- 风控前置校验
conversation-service
- 单聊会话
- 会话设置
- 会话列表
message-service
- 接收密文 envelope
- 分配 message_id / seq
- 存储与 fanout
group-service
- 创建群
- 加人/踢人/退群
- 群资料
- 维护 group_key_version
sync-service
- bootstrap
- 增量消息
- 群事件同步
push-service
- message.new
- message.recall
- group.member_changed
- device.revoked
file-ticket-service
- 上传票据
- 下载票据
- 文件元信息
risk-device-service
- 设备状态
- 完整性校验
- 风险拦截
5. 服务端数据模型
5.1 用户与设备
erDiagram
USER ||--o{ DEVICE : owns
USER {
string user_id
string status
int64 created_at
}
DEVICE {
string device_id
string user_id
string platform
string device_model
string app_version
string virgil_identity
string status
int64 last_seen_at
}
5.2 会话与消息
erDiagram
CONVERSATION ||--o{ MESSAGE : contains
CONVERSATION {
string conversation_id
string type
string peer_key
string group_id
int64 created_at
}
MESSAGE {
string message_id
string conversation_id
string chat_type
string sender_user_id
string sender_device_id
string receiver_user_id
string group_id
int64 group_key_version
string content_type
int envelope_version
string cipher_suite
bytes ciphertext
bytes signature
int64 seq
int64 server_timestamp
}
5.3 群与群事件
erDiagram
GROUP ||--o{ GROUP_MEMBER : has
GROUP ||--o{ GROUP_KEY_EVENT : emits
GROUP {
string group_id
string conversation_id
string owner_user_id
string name
int64 group_key_version
string status
}
GROUP_MEMBER {
string group_id
string user_id
string role
string status
int64 join_version
int64 leave_version
}
GROUP_KEY_EVENT {
string event_id
string group_id
int64 group_key_version
string event_type
string operator_user_id
int64 created_at
}
6. 服务端接口设计
6.1 认证与设备
登录
POST /api/v1/auth/login
刷新 token
POST /api/v1/auth/refresh
登出
POST /api/v1/auth/logout
注册设备
POST /api/v1/devices/register
查询设备列表
GET /api/v1/devices
吊销设备
POST /api/v1/devices/{device_id}:revoke
6.2 Virgil JWT
获取 Virgil JWT
POST /api/v1/security/virgil-jwt
请求:
{
"device_id": "ios_a1"
}
响应:
{
"virgil_jwt": "virgil_jwt_xxx",
"expires_in": 3600,
"virgil_identity": "u_1001:ios_a1"
}
6.3 会话
创建/获取单聊
POST /api/v1/conversations/single
会话列表
GET /api/v1/conversations
会话详情
GET /api/v1/conversations/{conversation_id}
会话设置
POST /api/v1/conversations/{conversation_id}/settings
6.4 消息
发送消息
POST /api/v1/messages
批量发送
POST /api/v1/messages:batchSend
拉取指定消息
GET /api/v1/messages/{message_id}
撤回消息
POST /api/v1/messages/{message_id}:recall
仅自己删除
POST /api/v1/messages/{message_id}:deleteForMe
6.5 群组
创建群
POST /api/v1/groups
群详情
GET /api/v1/groups/{group_id}
群上下文
GET /api/v1/groups/{group_id}/context
群成员列表
GET /api/v1/groups/{group_id}/members
加人
POST /api/v1/groups/{group_id}/members:add
移除成员
POST /api/v1/groups/{group_id}/members:remove
退群
POST /api/v1/groups/{group_id}:leave
解散群
POST /api/v1/groups/{group_id}:dismiss
修改群资料
POST /api/v1/groups/{group_id}/profile
6.6 文件
申请上传票据
POST /api/v1/files/upload-ticket
上传完成
POST /api/v1/files/{file_id}:complete
获取下载票据
POST /api/v1/files/{file_id}/download-ticket
获取文件元信息
GET /api/v1/files/{file_id}
6.7 同步
冷启动 bootstrap
GET /api/v1/sync/bootstrap
增量消息同步
GET /api/v1/sync/messages
群事件同步
GET /api/v1/sync/group-events
6.8 回执与状态
已送达/已读
POST /api/v1/messages/ack
批量已读
POST /api/v1/conversations/{conversation_id}:markRead
输入中
POST /api/v1/conversations/{conversation_id}/typing
6.9 风控与安全
预检查
POST /api/v1/security/precheck
设备完整性上报
POST /api/v1/security/integrity-report
7. 服务端核心流程
7.1 签发 Virgil JWT
sequenceDiagram
participant C as 客户端
participant J as Virgil JWT Service
participant A as Auth Service
participant R as Risk / Device Service
C->>J: /security/virgil-jwt
J->>A: 校验 access_token
A-->>J: 用户有效
J->>R: 校验 device_id / 风险状态
R-->>J: 允许或拒绝
J-->>C: 返回 virgil_jwt
7.2 消息接收与路由
sequenceDiagram
participant C as 客户端
participant M as Message Service
participant S as Sync Service
participant P as Push Service
participant DB as Metadata DB
C->>M: POST /messages
M->>DB: 存储 envelope
M->>DB: 分配 message_id / seq
M->>S: 写离线同步流
M->>P: 触发新消息推送
M-->>C: 返回 accepted
7.3 群成员变更
sequenceDiagram
participant A as 管理员客户端
participant G as Group Service
participant DB as Metadata DB
participant S as Sync Service
participant P as Push Service
A->>G: /groups/{id}/members:add
G->>DB: 更新群成员
G->>DB: group_key_version + 1
G->>S: 写入 group event
G->>P: 推送 group.member_changed
G-->>A: 返回最新 group_key_version
8. 服务端幂等与校验
8.1 幂等设计
发消息幂等键
推荐:
sender_user_id + sender_device_id + client_message_id
创建群幂等
推荐使用:
Idempotency-Key: <uuid>
8.2 消息接口校验项
- 当前用户是会话参与者
sender_device_id属于当前用户- 单聊的
receiver_user_id与会话匹配 - 群聊的
group_id与会话匹配 - 当前用户是群成员
group_key_version合法ciphertext长度不超过限制
8.3 Virgil JWT 接口校验项
- 业务 token 有效
device_id属于当前用户- 设备状态为 active
- 未被吊销
- 风控未阻断
9. WebSocket / 推送事件建议
WebSocket 事件
message.newmessage.recallmessage.ackgroup.member_changedgroup.profile_changeddevice.revokedsecurity.force_logout
推送原则
推送中不要放消息明文,建议只放:
- 会话 ID
- 发送方昵称
- 占位提示
10. 服务端风险点
- 若服务端误记录明文日志,会破坏 E2EE 边界
- 若文件下载链接长期有效,文件密文泄露面会扩大
- 若群成员变更后未提升
group_key_version,客户端可能使用旧上下文 - 若被吊销设备仍可获取 Virgil JWT,会造成安全失控
- 若推送带明文,会绕过加密链路
11. 推荐实施路径
阶段 1:单聊 MVP
实现:
- 登录
- Virgil JWT
- 单聊消息发送
- 增量同步
- 已读回执
阶段 2:群聊
实现:
- 创建群
- 群成员管理
- group_key_version
- 群事件同步
阶段 3:文件与恢复
实现:
- 文件票据
- 加密文件上传下载
- 新设备恢复
- 风控增强
12. 服务器总结
服务器在 Virgil Security 接入中的核心定位是:
- 不参与消息解密
- 不保存私钥
- 只处理密文、元数据和业务控制逻辑
具体来说,服务器负责:
- 身份认证
- 设备管理
- Virgil JWT 签发
- 密文消息接入、存储、路由
- 会话与群成员关系
- 文件票据
- 同步与推送
- 风控和设备吊销
这样才能既保留现有聊天系统的业务能力,又维持端到端加密的安全边界。