Files
Cyrene_v2/plugins/channels/weixin_ilink/aes.go
T
AskaEth 95f97f5df3
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
docs(comments): 注释中文化 · plugins/channels/weixin_ilink(20 文件,纯替换)
- 只翻注释/文档字符串:剥掉行尾注释后,每条「-」都有逐字节相同的「+」对应行(8 组,代码零改动)
- 保留协议/线上标识符原文:errcode、bot_token、context_token、getupdates、binded_redirect、PKCS#7、ECB 等
- 术语对齐既有译法:owner→主人、peer→对端、long poll→长轮询、backoff→退避、sentinel error→哨兵错误
- 已知既有欠债(未顺手修):login_reuse_test.go 在 HEAD 上就未 gofmt 干净;login_test.go 的 TestStartLogin_ScanStatusTransition 91 行 >80(HEAD 同为 91 行)
2026-10-04 12:29:05 +08:00

75 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package weixin_ilink
import (
"crypto/aes"
"errors"
"fmt"
)
// ErrBadCiphertext 在密文长度不是 AES 分组整数倍、或其填充格式非法时返回。
var ErrBadCiphertext = errors.New("weixin_ilink: bad ciphertext or padding")
// pkcs7Pad 按 PKCS#7 向 src 追加填充,使其长度成为 blockSize 的整数倍。
// 每个追加字节都写入填充长度,因此它是自描述的,Unpad 可以无歧义地剥离。
func pkcs7Pad(src []byte, blockSize int) []byte {
n := blockSize - len(src)%blockSize
out := make([]byte, len(src)+n)
copy(out, src)
for i := len(src); i < len(out); i++ {
out[i] = byte(n)
}
return out
}
// pkcs7Unpad 从 src 剥离 PKCS#7 填充。长度不是分组整数倍、或末尾填充字节不自洽
// 时返回 ErrBadCiphertext。
func pkcs7Unpad(src []byte, blockSize int) ([]byte, error) {
if len(src) == 0 || len(src)%blockSize != 0 {
return nil, ErrBadCiphertext
}
n := int(src[len(src)-1])
if n < 1 || n > blockSize {
return nil, ErrBadCiphertext
}
for _, b := range src[len(src)-n:] {
if int(b) != n {
return nil, ErrBadCiphertext
}
}
return src[:len(src)-n], nil
}
// aesECBEncrypt 用给定密钥以 ECB 模式对 src 做 AES 加密。Go 的 crypto/cipher
// 不提供 ECB,所以此模式在此自行实现:先把 src 填充到分组整数倍,再用同一密钥
// 逐块独立加密。ECB 是确定性的、不具备语义安全性;这里之所以需要它,仅仅是因为
// iLink CDN 协议对媒体负载强制要求该模式。
func aesECBEncrypt(key, src []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("weixin_ilink: new aes cipher: %w", err)
}
padded := pkcs7Pad(src, block.BlockSize())
out := make([]byte, len(padded))
for i := 0; i < len(padded); i += block.BlockSize() {
block.Encrypt(out[i:i+block.BlockSize()], padded[i:i+block.BlockSize()])
}
return out, nil
}
// aesECBDecrypt 用给定密钥对 src 做 AES 解密并剥离 PKCS#7 填充。ECB 没有 IV,
// 所以首块直接用密钥解密。输入格式非法时返回 ErrBadCiphertext。
func aesECBDecrypt(key, src []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("weixin_ilink: new aes cipher: %w", err)
}
if len(src) == 0 || len(src)%block.BlockSize() != 0 {
return nil, ErrBadCiphertext
}
out := make([]byte, len(src))
for i := 0; i < len(src); i += block.BlockSize() {
block.Decrypt(out[i:i+block.BlockSize()], src[i:i+block.BlockSize()])
}
return pkcs7Unpad(out, block.BlockSize())
}