Files
Cyrene_v2/plugins/channels/weixin_ilink/aes_test.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

110 lines
3.3 KiB
Go

package weixin_ilink
import (
"bytes"
"crypto/aes"
"errors"
"strconv"
"testing"
)
func TestAESECB_RoundTrip_AllBlockBoundaries(t *testing.T) {
t.Parallel()
key := bytes.Repeat([]byte{0x42}, aes.BlockSize)
// 覆盖长度 0 到刚过两个分组的范围(填充边界情况)。
for n := 0; n <= 2*aes.BlockSize+5; n++ {
n := n
t.Run("len="+strconv.Itoa(n), func(t *testing.T) {
t.Parallel()
pt := bytes.Repeat([]byte{0xAB}, n)
ct, err := aesECBEncrypt(key, pt)
if err != nil {
t.Fatalf("aesECBEncrypt: %v", err)
}
got, err := aesECBDecrypt(key, ct)
if err != nil {
t.Fatalf("aesECBDecrypt: %v", err)
}
if !bytes.Equal(got, pt) {
t.Fatalf("round trip mismatch: got %x want %x", got, pt)
}
})
}
}
func TestAESECB_EncryptPadsToBlockSize(t *testing.T) {
t.Parallel()
key := bytes.Repeat([]byte{1}, aes.BlockSize)
ct, err := aesECBEncrypt(key, []byte("abc")) // 3 字节 -> 填充后 16 字节
if err != nil {
t.Fatalf("aesECBEncrypt: %v", err)
}
if len(ct) != aes.BlockSize {
t.Fatalf("ciphertext = %d bytes, want %d", len(ct), aes.BlockSize)
}
// 整块输入 -> 追加一个填充块。
ct2, err := aesECBEncrypt(key, bytes.Repeat([]byte{0}, aes.BlockSize))
if err != nil {
t.Fatalf("aesECBEncrypt: %v", err)
}
if len(ct2) != 2*aes.BlockSize {
t.Fatalf("full-block ciphertext = %d bytes, want %d", len(ct2), 2*aes.BlockSize)
}
}
func TestAESECB_DecryptRejectsBadLength(t *testing.T) {
t.Parallel()
key := bytes.Repeat([]byte{2}, aes.BlockSize)
cases := []int{0, 5, aes.BlockSize - 1, aes.BlockSize + 1}
for _, n := range cases {
n := n
t.Run("len="+strconv.Itoa(n), func(t *testing.T) {
t.Parallel()
_, err := aesECBDecrypt(key, make([]byte, n))
if !errors.Is(err, ErrBadCiphertext) {
t.Fatalf("err = %v, want ErrBadCiphertext", err)
}
})
}
}
func TestAESECB_DecryptRejectsBadPadding(t *testing.T) {
t.Parallel()
key := bytes.Repeat([]byte{3}, aes.BlockSize)
// 一个分组、填充正确(0x10)的合法密文……
good, err := aesECBEncrypt(key, bytes.Repeat([]byte{4}, aes.BlockSize-1))
if err != nil {
t.Fatalf("aesECBEncrypt: %v", err)
}
// ……然后篡改末尾填充字节,使填充校验必然失败。
bad := append([]byte(nil), good...)
bad[len(bad)-1] ^= 0xFF
_, err = aesECBDecrypt(key, bad)
if !errors.Is(err, ErrBadCiphertext) {
t.Fatalf("err = %v, want ErrBadCiphertext", err)
}
}
func TestAESECB_KeySizesAccepted(t *testing.T) {
t.Parallel()
// AES-128 需要 16 字节密钥。验证超范围的密钥会被拒绝。
if _, err := aesECBEncrypt(bytes.Repeat([]byte{1}, aes.BlockSize-1), []byte("x")); err == nil {
t.Fatal("short key: expected error, got nil")
}
if _, err := aesECBEncrypt(bytes.Repeat([]byte{1}, aes.BlockSize+1), []byte("x")); err == nil {
t.Fatal("long key: expected error, got nil")
}
}
func TestPKCS7_UnpadRejectsInvalid(t *testing.T) {
t.Parallel()
// 填充字节多于一个分组。
if _, err := pkcs7Unpad([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, 16); !errors.Is(err, ErrBadCiphertext) {
t.Fatalf("oversize pad: err = %v, want ErrBadCiphertext", err)
}
// 填充字节为 0 永远非法。
if _, err := pkcs7Unpad([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0}, 16); !errors.Is(err, ErrBadCiphertext) {
t.Fatalf("zero pad: err = %v, want ErrBadCiphertext", err)
}
}