解密飞书事件的 encrypt 密文。
飞书在开启加密推送后,会将事件体加密为一段 Base64 字符串放在 encrypt 字段中。
其算法为 AES-256-CBC:密钥取 sha256(encrypt_key),前 16 字节为 IV,采用 PKCS7 填充。
参数:
| 名称 |
类型 |
描述 |
默认 |
encrypt_key
|
str
|
应用在飞书开放平台配置的 Encrypt Key。
|
必需
|
b64_ciphertext
|
str
|
|
必需
|
返回:
| 类型 |
描述 |
bytes
|
解密并去除填充后的原始明文字节(通常是一段 JSON)。
|
引发:
| 类型 |
描述 |
[feishu.errors.FeishuCryptoError][]
|
当 Base64 非法、密文长度不足一个 AES 块,
或密钥错误导致去填充失败时抛出。
|
飞书文档
订阅事件
示例:
| Python Console Session |
|---|
| >>> decrypt("test key", "P37w+VZImNgPEO1RBhJ6RtKl7n6zymIbEG1pReEzghk=")
b'hello world'
>>> try:
... decrypt("test key", "!!!not base64!!!")
... except FeishuCryptoError as exc:
... print(type(exc).__name__)
FeishuCryptoError
|
源代码位于: feishu/events/crypto.py
| Python |
|---|
| def decrypt(encrypt_key: str, b64_ciphertext: str) -> bytes:
r"""
解密飞书事件的 `encrypt` 密文。
飞书在开启加密推送后,会将事件体加密为一段 Base64 字符串放在 `encrypt` 字段中。
其算法为 AES-256-CBC:密钥取 `sha256(encrypt_key)`,前 16 字节为 IV,采用 PKCS7 填充。
Args:
encrypt_key: 应用在飞书开放平台配置的 Encrypt Key。
b64_ciphertext: `encrypt` 字段中的 Base64 密文。
Returns:
解密并去除填充后的原始明文字节(通常是一段 JSON)。
Raises:
[feishu.errors.FeishuCryptoError][]: 当 Base64 非法、密文长度不足一个 AES 块,
或密钥错误导致去填充失败时抛出。
飞书文档:
[订阅事件](https://open.feishu.cn/document/server-docs/event-subscription-guide/event-subscription-configure-/encrypt-key-encryption-configuration-case)
Examples:
>>> decrypt("test key", "P37w+VZImNgPEO1RBhJ6RtKl7n6zymIbEG1pReEzghk=")
b'hello world'
>>> try:
... decrypt("test key", "!!!not base64!!!")
... except FeishuCryptoError as exc:
... print(type(exc).__name__)
FeishuCryptoError
"""
# AES loads native-library handles, which must be created after a runtime snapshot is restored.
from Crypto.Cipher import AES
key = hashlib.sha256(encrypt_key.encode("utf-8")).digest()
try:
blob = base64.b64decode(b64_ciphertext)
except ValueError as exc:
raise FeishuCryptoError(-1, f"invalid base64 ciphertext: {exc}") from exc
if len(blob) < 16:
raise FeishuCryptoError(-1, "ciphertext shorter than one AES block")
iv, ct = blob[:16], blob[16:]
try:
plain = AES.new(key, AES.MODE_CBC, iv).decrypt(ct)
return unpad(plain, AES.block_size)
except ValueError as exc:
raise FeishuCryptoError(-1, f"decrypt/unpad failed: {exc}") from exc
|