test: OTP 算法 + 加密 + Config + QR 导出 单元测试
- authenticator: HOTP RFC 4226 向量、Base32 往返、SecretData 往返 - crypto: WAGO1 加密解密往返、错误密码、空密码、无效载荷 - config: YAML 明文/加密读写、密码错误、.bak 轮换 - qr: EntryToOtpAuth 各 vendor、URI 往返、默认值省略
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestModernRoundTrip encrypts then decrypts and verifies the plaintext
|
||||
// comes back unchanged for various payload sizes.
|
||||
func TestModernRoundTrip(t *testing.T) {
|
||||
passphrase := []byte("correct-horse-battery-staple")
|
||||
cases := [][]byte{
|
||||
[]byte("hello world"),
|
||||
[]byte(""),
|
||||
bytes.Repeat([]byte("x"), 1024),
|
||||
{0x00, 0x01, 0x02, 0xFF},
|
||||
}
|
||||
for _, pt := range cases {
|
||||
enc, err := EncryptModern(pt, passphrase)
|
||||
if err != nil {
|
||||
t.Fatalf("EncryptModern error: %v", err)
|
||||
}
|
||||
dec, err := DecryptModern(enc, passphrase)
|
||||
if err != nil {
|
||||
t.Fatalf("DecryptModern error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(dec, pt) {
|
||||
t.Errorf("round-trip mismatch: got %x, want %x", dec, pt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestModernWrongPassword verifies that decrypting with the wrong
|
||||
// passphrase produces an error.
|
||||
func TestModernWrongPassword(t *testing.T) {
|
||||
enc, err := EncryptModern([]byte("secret data"), []byte("password1"))
|
||||
if err != nil {
|
||||
t.Fatalf("EncryptModern error: %v", err)
|
||||
}
|
||||
if _, err := DecryptModern(enc, []byte("password2")); err == nil {
|
||||
t.Error("expected error for wrong password")
|
||||
}
|
||||
}
|
||||
|
||||
// TestModernEmptyPassword verifies that an empty passphrase works
|
||||
// (callers use this for unencrypted configs internally).
|
||||
func TestModernEmptyPassword(t *testing.T) {
|
||||
pt := []byte("some data")
|
||||
enc, err := EncryptModern(pt, []byte{})
|
||||
if err != nil {
|
||||
t.Fatalf("EncryptModern error: %v", err)
|
||||
}
|
||||
dec, err := DecryptModern(enc, []byte{})
|
||||
if err != nil {
|
||||
t.Fatalf("DecryptModern error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(dec, pt) {
|
||||
t.Errorf("round-trip mismatch: got %x, want %x", dec, pt)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDecryptModernInvalidPayload verifies that malformed payloads are
|
||||
// rejected cleanly.
|
||||
func TestDecryptModernInvalidPayload(t *testing.T) {
|
||||
cases := []string{
|
||||
"", // empty
|
||||
"WAGO1", // no base64 payload
|
||||
"XXXX" + "AAAA", // wrong prefix
|
||||
"WAGO1AAAA", // too short after base64 decode
|
||||
}
|
||||
for _, c := range cases {
|
||||
if _, err := DecryptModern(c, []byte("pw")); err == nil {
|
||||
t.Errorf("expected error for payload %q", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestDerivePBKDF2SHA1Deterministic verifies that the legacy PBKDF2-SHA1
|
||||
// key derivation is deterministic for a fixed (password, salt) pair.
|
||||
func TestDerivePBKDF2SHA1Deterministic(t *testing.T) {
|
||||
pw := []byte("test")
|
||||
salt := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
key1 := DerivePBKDF2SHA1(pw, salt)
|
||||
key2 := DerivePBKDF2SHA1(pw, salt)
|
||||
if !bytes.Equal(key1, key2) {
|
||||
t.Error("DerivePBKDF2SHA1 not deterministic")
|
||||
}
|
||||
if len(key1) != 32 {
|
||||
t.Errorf("key length = %d, want 32", len(key1))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user