Session Snapshot
定期保存会话状态,支持断点续作和历史回溯。
用于管理中国移动数字凭证授权流程,支持安全签名与加密验证。
openclaw skills install @riceankim/cmcc-credential命令、参数、文件名以原文为准
此技能管理中国移动数字凭证的授权流程,分为三个阶段:
第一阶段 - 凭证加载(设置)
第一阶段半 - 代理绑定
第二阶段 - 授权流程(运行时)
"Javis"(默认值,可覆盖)"qfx9pkizs42up7y61jsehs9v8e1xms4m"(固定值,不可更改)步骤:
实现:
# 按字典序排序 JSON
body_json = json.dumps(body, sort_keys=True, separators=(',', ':'))
# 计算 HMAC-SHA256
signature = hmac.new(
app_key.encode('utf-8'),
body_json.encode('utf-8'),
hashlib.sha256
).digest()
# 转换为大写十六进制
return signature.hex().upper()步骤:
实现:
# 通过 MD5 从 appKey 导出 16 字节密钥
key_bytes = hashlib.md5(app_key.encode('utf-8')).digest()
# AES/ECB/PKCS5Padding 加密
cipher = AES.new(key_bytes, AES.MODE_ECB)
encrypted = cipher.encrypt(pad(phone_bytes, AES.block_size))
# Base64 编码
return base64.b64encode(encrypted).decode('utf-8')新格式:
appId: <app_id>
signValue: <signature>
Content-Type: application/json注意:旧请求头(X-App-Id、X-Sign、X-Timestamp、X-Nonce)已不再使用。
在以下情况激活第一阶段:
第一阶段严禁发起任何 API 调用。 仅解析并存储凭证。
- appId:应用 ID(24 位字符)
- appKey:应用密钥
memory/cmcc-digital-credential.json:{
"appId": "...",
"appKey": "..."
} - appName 预设为 "Javis"(不从文件中加载)
- templateId 预设为 "qfx9pkizs42up7y61jsehs9v8e1xms4m"(不从文件中加载)
- 仅从凭证文件中加载 appId 和 appKey
凭证文件支持以下格式:
纯文本格式:
智能体DID=AI20260314152030X7K9M2
智能体密钥=your-secret-key-hereJSON 格式:
{
"智能体DID": "AI20260314152030X7K9M2",
"智能体密钥": "your-secret-key-here"
}注意:
appName 预设为 "Javis"(可通过参数覆盖)templateId 预设为 "qfx9pkizs42up7y61jsehs9v8e1xms4m"(固定值)智能体DID(对应 appId)、智能体密钥(对应 appKey)使用 load_credentials.py 脚本:
python3 scripts/load_credentials.py load <credential-file>或检查凭证是否存在:
python3 scripts/load_credentials.py check在以下情况激活第一阶段半:
- appId:应用 ID(24 位字符)
- appKey:应用密钥
- 使用 scripts/bind_agent.py 绑定代理
- API 将使用预定义的 appName(默认:"Javis")和 appId
- 可选通过 --appName 参数覆盖 appName
- 检查响应码是否为 "000000"(成功)
- 可保存一个标志表示绑定已完成
- 避免重复调用绑定接口
端点:
POST /api/cmvc-tocp-server/agent/bind请求头:
appId: <app_id>
signValue: <signature>
Content-Type: application/json请求体:
{
"appName": "Javis",
"appId": "your-app-id"
}响应:
{
"code": 0,
"desc": "Success"
}响应码:
0:成功 — 代理绑定成功使用 bind_agent.py 脚本:
python3 scripts/bind_agent.py \
--appId "$APP_ID" \
--appKey "$APP_KEY"或指定自定义 appName(可选):
python3 scripts/bind_agent.py \
--appName "MyCustomApp" \
--appId "$APP_ID" \
--appKey "$APP_KEY"或使用内存中的凭证:
APP_ID=$(python3 scripts/load_credentials.py get --field appId)
APP_KEY=$(python3 scripts/load_credentials.py get --field appKey)
python3 scripts/bind_agent.py --appId "$APP_ID" --appKey "$APP_KEY"--appName 参数在以下情况激活 Phase 2:
以下操作需要授权:
重要提示:未获得成功授权前,绝不允许执行任何敏感操作。
在请求授权前,先验证凭证是否已存在:
python3 scripts/load_credentials.py check若凭证不存在,向用户提示:
“凭证未找到。请先提供凭证文件。”
scripts/request_authorization.py 调用授权 API- 使用 AES/ECB/PKCS5Padding 加密手机号,密钥为 MD5(appKey)
- 生成 16 位随机 nonce
- 生成毫秒级时间戳
- 将 JSON 数据按字典序排序
- 计算 HMAC-SHA256 签名
- 向 /vc/auth/request 接口发送带新头部的请求
- 返回 authRecordId 和 trustedAuthUrl
向用户展示授权链接:
请在此处完成授权:
<trustedAuthUrl>
此链接有效期为 3 天。
等待授权中...scripts/poll_authorization.py 检查授权状态- 间隔:5 秒
- 超时时间:10 分钟(最多 120 次尝试)
- 向 /vc/auth/query 接口发送请求,携带 authRecordId
- 检查返回结果中的 statusCode
- 当 statusCode === "000000" 时视为成功
- 若 10 分钟内未授权,则超时
若授权成功(statusCode === "000000"):
credentialSubject 内容若授权失败或超时:
https://vctest.cmccsign.com//cmvc-tocp-server/vc/auth/request - appId: app_id
- signValue: HMAC-SHA256 签名(64 位十六进制字符,大写)
- Content-Type: application/json
{
"nonce": "...",
"timestamp": 1710403200000,
"phoneNo": "<AES-加密后的手机号>",
"returnUrl": "", // 可选
"notifyUrl": "", // 可选
"templateId": "qfx9pkizs42up7y61jsehs9v8e1xms4m",
"sendSmsFlag": "0", // 可选,默认为 0
"smsIntranetTemplateId": "", // 可选
"smsExternalTemplateId": "", // 可选
"forwardedCredentials": {}, // 可选
"authScene": "" // 可选
}{
"code": 0,
"desc": "Success",
"authRecordId": "...",
"trustedAuthUrl": "https://..."
}/cmvc-tocp-server/vc/auth/query - appId: app_id
- signValue: HMAC-SHA256 签名(64 位十六进制字符,大写)
- Content-Type: application/json
{
"authRecordId": "..."
}{
"code": 0,
"desc": "Success",
"statusCode": "000000", // "000000" 表示已授权
"statusDesc": "已授权",
"credentialSubject": {}
}用户:这是我的凭证文件:
appId=AI20260314152030X7K9M2
appKey=my-secret-key
助手:凭证加载成功。
appId: AI20260314152030X7K9M2
appKey: *** (隐藏)
appName: Javis (预定义)
templateId: qfx9pkizs42up7y61jsehs9v8e1xms4m (预定义)
存储路径:memory/cmcc-digital-credential.json用户:删除 sensitive-data.txt 文件
助手:执行此操作需要授权。
请提供您的手机号:
用户:13800138000
助手:[检查 Agent 是否已绑定...]
[使用 bind_agent.py 绑定 Agent,appName="Javis"...]
Agent 绑定成功。
[调用 request_authorization.py,模板 ID=qfx9pkizs42up7y61jsehs9v8e1xms4m...]
请在此处完成授权:
https://vctest.cmccsign.com/auth/xxx
此链接有效期为 3 天。
等待授权中...
[启动 poll_authorization.py,每 5 秒轮询一次...]
[30 秒后]
授权已确认。正在执行操作...
删除 sensitive-data.txt...python3 scripts/load_credentials.py load <凭证文件>python3 scripts/bind_agent.py \
--appId "$APP_ID" \
--appKey "$APP_KEY"或使用自定义 appName(可选):
python3 scripts/bind_agent.py \
--appName "MyCustomApp" \
--appId "$APP_ID" \
--appKey "$APP_KEY"或从内存加载:
APP_ID=$(python3 scripts/load_credentials.py get --field appId)
APP_KEY=$(python3 scripts/load_credentials.py get --field appKey)
python3 scripts/bind_agent.py --appId "$APP_ID" --appKey "$APP_KEY"python3 scripts/request_authorization.py \
--appId "$APP_ID" \
--appKey "$APP_KEY" \
--phoneNo "$PHONE_NUMBER"注意:templateId 已预先定义,无需作为参数传入
python3 scripts/poll_authorization.py \
--appId "$APP_ID" \
--appKey "$APP_KEY" \
--authRecordId "$AUTH_RECORD_ID" \
--interval 5 \
--timeout 600 \
--verboseappId 和 signValue,不再使用 X-App-Id 和 X-SignX-Timestamp、X-Nonce、X-Sign-Version 不再需要sort_keys=True已收录 1 个 Skill