90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
package crypto_test
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/veylant/ia-gateway/internal/crypto"
|
|
)
|
|
|
|
// validKey returns a base64-encoded 32-byte key for tests.
|
|
func validKey() string {
|
|
return base64.StdEncoding.EncodeToString([]byte("01234567890123456789012345678901"))
|
|
}
|
|
|
|
func newEncryptor(t *testing.T) *crypto.Encryptor {
|
|
t.Helper()
|
|
enc, err := crypto.NewEncryptor(validKey())
|
|
require.NoError(t, err)
|
|
return enc
|
|
}
|
|
|
|
func TestAES_Roundtrip(t *testing.T) {
|
|
enc := newEncryptor(t)
|
|
plaintext := "Mon numéro de sécu est 1 85 06 75 116 097 42"
|
|
|
|
ciphertext, err := enc.Encrypt(plaintext)
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, ciphertext)
|
|
assert.NotEqual(t, plaintext, ciphertext)
|
|
|
|
decrypted, err := enc.Decrypt(ciphertext)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, plaintext, decrypted)
|
|
}
|
|
|
|
func TestAES_NonceUnique(t *testing.T) {
|
|
enc := newEncryptor(t)
|
|
plaintext := "same plaintext"
|
|
|
|
ct1, err := enc.Encrypt(plaintext)
|
|
require.NoError(t, err)
|
|
ct2, err := enc.Encrypt(plaintext)
|
|
require.NoError(t, err)
|
|
|
|
// Two encryptions of the same plaintext must produce different ciphertexts
|
|
// because nonces are random.
|
|
assert.NotEqual(t, ct1, ct2)
|
|
}
|
|
|
|
func TestAES_EmptyPlaintext(t *testing.T) {
|
|
enc := newEncryptor(t)
|
|
|
|
ciphertext, err := enc.Encrypt("")
|
|
require.NoError(t, err)
|
|
|
|
decrypted, err := enc.Decrypt(ciphertext)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "", decrypted)
|
|
}
|
|
|
|
func TestAES_InvalidKey(t *testing.T) {
|
|
// 16-byte key (too short for AES-256)
|
|
shortKey := base64.StdEncoding.EncodeToString([]byte("0123456789abcdef"))
|
|
_, err := crypto.NewEncryptor(shortKey)
|
|
assert.Error(t, err)
|
|
assert.True(t, strings.Contains(err.Error(), "32 bytes"))
|
|
}
|
|
|
|
func TestAES_DecryptTampered(t *testing.T) {
|
|
enc := newEncryptor(t)
|
|
|
|
ct, err := enc.Encrypt("some sensitive data")
|
|
require.NoError(t, err)
|
|
|
|
// Corrupt the last character of the base64 ciphertext.
|
|
runes := []rune(ct)
|
|
runes[len(runes)-1] = 'X'
|
|
if runes[len(runes)-1] == []rune(ct)[len(runes)-1] {
|
|
runes[len(runes)-1] = 'Y'
|
|
}
|
|
tampered := string(runes)
|
|
|
|
_, err = enc.Decrypt(tampered)
|
|
assert.Error(t, err, "decrypting tampered ciphertext should fail")
|
|
}
|