跳转到内容

端到端加密 (E2EE)

PushGo 的 E2EE 设计用于保护敏感业务字段。发送方把要保护的字段加密后放入 ciphertext,Gateway 只负责透传密文;客户端在本地配置密钥后解密并覆盖展示字段。

内容是否由 E2EE 保护说明
放入 ciphertext 的业务字段Gateway 无法读取明文。
明文请求字段例如 channel_idpasswordseverity、路由字段仍按普通请求处理。
HTTP Header依赖 HTTPS/TLS 保护。
投递元数据Gateway 仍需要基本元数据完成鉴权、路由和分发。

E2EE 不是网关鉴权的替代品。你仍然需要频道密码、可选的 Gateway Bearer Token 和 HTTPS。

PushGo 客户端支持 AES-GCM。密钥长度决定算法位数。

密钥长度算法Nonce / IVAuth Tag
16 字节AES-128-GCM12 字节16 字节
24 字节AES-192-GCM12 字节16 字节
32 字节AES-256-GCM12 字节16 字节

二进制布局:

[ ciphertext (N bytes) ][ auth tag (16 bytes) ][ nonce / iv (12 bytes) ]

最后把这段二进制整体 Base64 编码,填入 API 的 ciphertext 字段。

ciphertext 解密后必须是 JSON 对象。客户端会识别以下 canonical 字段,并把它们写回通知载荷。

字段类型行为
titlestring覆盖通知标题。
bodystring覆盖消息正文。
urlstring覆盖点击跳转 URL。
imagesstring[] 或 JSON 字符串覆盖图片列表。
tagsstring[] 或 JSON 字符串覆盖标签列表。
metadataobject 或 JSON 字符串覆盖 metadata。
字段类型行为
descriptionstring覆盖事件描述。
statusstring覆盖事件状态。
messagestring覆盖事件消息。
started_atnumber覆盖事件开始时间。
ended_atnumber覆盖事件结束时间。
attrsobject 或 JSON 字符串覆盖事件 attrs patch。
字段类型行为
primary_imagestring覆盖主图。
statestring覆盖实体状态。
created_atnumber覆盖创建时间。
deleted_atnumber覆盖删除时间。
external_idsobject 或 JSON 字符串覆盖外部 ID。
location_typestring覆盖位置类型。
location_valuestring覆盖位置值。
locationobject 或 JSON 字符串覆盖位置对象。
import base64
import json
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
def encrypt_payload(key_hex, payload):
key = bytes.fromhex(key_hex)
aesgcm = AESGCM(key)
nonce = os.urandom(12)
plaintext = json.dumps(payload, separators=(",", ":")).encode("utf-8")
cipher_and_tag = aesgcm.encrypt(nonce, plaintext, None)
return base64.b64encode(cipher_and_tag + nonce).decode("utf-8")
payload = {
"title": "数据库延迟",
"body": "从库延迟超过 60 秒。",
"tags": ["encrypted", "database"],
"metadata": {"source": "replica-monitor"}
}
key_hex = "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
print(encrypt_payload(key_hex, payload))

key_hex 示例是 32 字节密钥,也就是 AES-256-GCM。实际生产中请使用安全随机密钥,并在客户端本地配置同一密钥。

Terminal window
curl -X POST https://gateway.pushgo.cn/message \
-H "Content-Type: application/json" \
-d '{
"channel_id": "YOUR_CHANNEL_ID",
"password": "YOUR_CHANNEL_PASSWORD",
"title": "加密消息",
"body": "你的客户端将尝试解密 ciphertext。",
"severity": "normal",
"ciphertext": "BASE64_ENCODED_CIPHERTEXT"
}'

明文 titlebody 可以作为未配置密钥或解密失败时的退化展示;真正敏感内容应放入 ciphertext

客户端可能展示以下状态:

状态含义
decryptOk已成功解密并应用至少一个字段。
decryptFailed存在密文,但解密或 JSON 解析失败。
notConfigured客户端未配置可用密钥。
algMismatch客户端配置的算法与载荷不匹配。
问题检查项
解密失败密钥是否一致;Base64 是否完整;二进制布局是否为 ciphertext + tag + nonce
客户端没有覆盖字段解密后的 JSON 是否是对象;字段名是否使用 canonical 名称。
Gateway 仍能看到标题标题如果放在明文字段中就不会被 E2EE 保护;敏感标题也应放入 ciphertext
severity 没被加密这是推荐做法,因为 Gateway 和系统推送需要优先级信息进行投递。