From 0349e7e463521b63fa6e618d80770fbe6176bb02 Mon Sep 17 00:00:00 2001 From: Fabio Bozzo Date: Thu, 28 Nov 2024 16:16:04 +0100 Subject: [PATCH 1/3] feat(meta): secretbox encryption in place of aes-gcm --- pkg/meta/internal/crypto/aes.go | 132 ------------------ pkg/meta/internal/crypto/secretbox.go | 89 ++++++++++++ .../crypto/{aes_test.go => secretbox_test.go} | 62 +++++--- pkg/meta/meta.go | 8 +- 4 files changed, 134 insertions(+), 157 deletions(-) delete mode 100644 pkg/meta/internal/crypto/aes.go create mode 100644 pkg/meta/internal/crypto/secretbox.go rename pkg/meta/internal/crypto/{aes_test.go => secretbox_test.go} (53%) diff --git a/pkg/meta/internal/crypto/aes.go b/pkg/meta/internal/crypto/aes.go deleted file mode 100644 index 482402e..0000000 --- a/pkg/meta/internal/crypto/aes.go +++ /dev/null @@ -1,132 +0,0 @@ -package crypto - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "errors" - "fmt" - "io" -) - -// KeySize represents valid AES key sizes -type KeySize int - -const ( - KeySize128 KeySize = 16 // AES-128 - KeySize192 KeySize = 24 // AES-192 - KeySize256 KeySize = 32 // AES-256 (recommended) -) - -// IsValid returns true if the key size is valid for AES -func (ks KeySize) IsValid() bool { - switch ks { - case KeySize128, KeySize192, KeySize256: - return true - default: - return false - } -} - -var ErrShortCipherText = errors.New("ciphertext too short") -var ErrNoEncryptionKey = errors.New("encryption key is required") -var ErrInvalidKeySize = errors.New("invalid key size: must be 16, 24, or 32 bytes") -var ErrZeroKey = errors.New("encryption key cannot be all zeros") - -// GenerateKey generates a random AES key of default size KeySize256 (32 bytes). -// Returns an error if the specified size is invalid or if key generation fails. -func GenerateKey() ([]byte, error) { - return GenerateKeyWithSize(KeySize256) -} - -// GenerateKeyWithSize generates a random AES key of the specified size. -// Returns an error if the specified size is invalid or if key generation fails. -func GenerateKeyWithSize(size KeySize) ([]byte, error) { - if !size.IsValid() { - return nil, ErrInvalidKeySize - } - - key := make([]byte, size) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - return nil, fmt.Errorf("failed to generate AES key: %w", err) - } - - return key, nil -} - -// EncryptWithAESKey encrypts data using AES-GCM with the provided key. -// The key must be 16, 24, or 32 bytes long (for AES-128, AES-192, or AES-256). -// Returns the encrypted data with the nonce prepended, or an error if encryption fails. -func EncryptWithAESKey(data, key []byte) ([]byte, error) { - if err := validateAESKey(key); err != nil { - return nil, err - } - - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(block) - if err != nil { - return nil, err - } - - nonce := make([]byte, gcm.NonceSize()) - if _, err = io.ReadFull(rand.Reader, nonce); err != nil { - return nil, err - } - - return gcm.Seal(nonce, nonce, data, nil), nil -} - -// DecryptStringWithAESKey decrypts data that was encrypted with EncryptWithAESKey. -// The key must match the one used for encryption. -// Expects the input to have a prepended nonce. -// Returns the decrypted data or an error if decryption fails. -func DecryptStringWithAESKey(data, key []byte) ([]byte, error) { - if err := validateAESKey(key); err != nil { - return nil, err - } - - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(block) - if err != nil { - return nil, err - } - - if len(data) < gcm.NonceSize() { - return nil, ErrShortCipherText - } - - nonce, ciphertext := data[:gcm.NonceSize()], data[gcm.NonceSize():] - decrypted, err := gcm.Open(nil, nonce, ciphertext, nil) - if err != nil { - return nil, err - } - - return decrypted, nil -} - -func validateAESKey(key []byte) error { - if key == nil { - return ErrNoEncryptionKey - } - - if !KeySize(len(key)).IsValid() { - return ErrInvalidKeySize - } - - // check if key is all zeros - for _, b := range key { - if b != 0 { - return nil - } - } - - return ErrZeroKey -} diff --git a/pkg/meta/internal/crypto/secretbox.go b/pkg/meta/internal/crypto/secretbox.go new file mode 100644 index 0000000..70d223c --- /dev/null +++ b/pkg/meta/internal/crypto/secretbox.go @@ -0,0 +1,89 @@ +package crypto + +import ( + "crypto/rand" + "errors" + "fmt" + "io" + + "golang.org/x/crypto/nacl/secretbox" +) + +const keySize = 32 // secretbox allows only 32-byte keys + +var ErrShortCipherText = errors.New("ciphertext too short") +var ErrNoEncryptionKey = errors.New("encryption key is required") +var ErrInvalidKeySize = errors.New("invalid key size: must be 32 bytes") +var ErrZeroKey = errors.New("encryption key cannot be all zeros") + +// GenerateKey generates a random 32-byte key to be used by EncryptWithKey and DecryptWithKey +func GenerateKey() ([]byte, error) { + key := make([]byte, keySize) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + return nil, fmt.Errorf("failed to generate key: %w", err) + } + return key, nil +} + +// EncryptWithKey encrypts data using secretbox with the provided key +func EncryptWithKey(data, key []byte) ([]byte, error) { + if err := validateKey(key); err != nil { + return nil, err + } + + var secretKey [keySize]byte + copy(secretKey[:], key) + + // Generate 24 bytes of random data as nonce + var nonce [24]byte + if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { + return nil, err + } + + // Encrypt and authenticate data + encrypted := secretbox.Seal(nonce[:], data, &nonce, &secretKey) + return encrypted, nil +} + +// DecryptStringWithKey decrypts data using secretbox with the provided key +func DecryptStringWithKey(data, key []byte) ([]byte, error) { + if err := validateKey(key); err != nil { + return nil, err + } + + if len(data) < 24 { + return nil, ErrShortCipherText + } + + var secretKey [keySize]byte + copy(secretKey[:], key) + + var nonce [24]byte + copy(nonce[:], data[:24]) + + decrypted, ok := secretbox.Open(nil, data[24:], &nonce, &secretKey) + if !ok { + return nil, errors.New("decryption failed") + } + + return decrypted, nil +} + +func validateKey(key []byte) error { + if key == nil { + return ErrNoEncryptionKey + } + + if len(key) != keySize { + return ErrInvalidKeySize + } + + // check if key is all zeros + for _, b := range key { + if b != 0 { + return nil + } + } + + return ErrZeroKey +} diff --git a/pkg/meta/internal/crypto/aes_test.go b/pkg/meta/internal/crypto/secretbox_test.go similarity index 53% rename from pkg/meta/internal/crypto/aes_test.go rename to pkg/meta/internal/crypto/secretbox_test.go index 1d0d3e4..d87f860 100644 --- a/pkg/meta/internal/crypto/aes_test.go +++ b/pkg/meta/internal/crypto/secretbox_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/require" ) -func TestAESEncryption(t *testing.T) { +func TestSecretBoxEncryption(t *testing.T) { t.Parallel() - key := make([]byte, 32) // generated random 32-byte key + key := make([]byte, keySize) // generate random 32-byte key _, errKey := rand.Read(key) require.NoError(t, errKey) @@ -40,13 +40,13 @@ func TestAESEncryption(t *testing.T) { { name: "invalid key size", data: []byte("hello world"), - key: make([]byte, 31), + key: make([]byte, 16), // Only 32 bytes allowed now wantErr: ErrInvalidKeySize, }, { name: "zero key returns error", data: []byte("hello world"), - key: make([]byte, 32), + key: make([]byte, keySize), wantErr: ErrZeroKey, }, } @@ -56,24 +56,22 @@ func TestAESEncryption(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - encrypted, err := EncryptWithAESKey(tt.data, tt.key) + encrypted, err := EncryptWithKey(tt.data, tt.key) if tt.wantErr != nil { require.ErrorIs(t, err, tt.wantErr) - return } require.NoError(t, err) - decrypted, err := DecryptStringWithAESKey(encrypted, tt.key) - require.NoError(t, err) - - if tt.key == nil { - require.Equal(t, tt.data, encrypted) - require.Equal(t, tt.data, decrypted) - } else { - require.NotEqual(t, tt.data, encrypted) - require.True(t, bytes.Equal(tt.data, decrypted)) + // Verify encrypted data is different and includes nonce + require.Greater(t, len(encrypted), 24) // At least nonce size + if len(tt.data) > 0 { + require.NotEqual(t, tt.data, encrypted[24:]) // Ignore nonce prefix } + + decrypted, err := DecryptStringWithKey(encrypted, tt.key) + require.NoError(t, err) + require.True(t, bytes.Equal(tt.data, decrypted)) }) } } @@ -81,10 +79,15 @@ func TestAESEncryption(t *testing.T) { func TestDecryptionErrors(t *testing.T) { t.Parallel() - key := make([]byte, 32) + key := make([]byte, keySize) _, err := rand.Read(key) require.NoError(t, err) + // Create valid encrypted data for tampering tests + validData := []byte("test message") + encrypted, err := EncryptWithKey(validData, key) + require.NoError(t, err) + tests := []struct { name string data []byte @@ -93,19 +96,25 @@ func TestDecryptionErrors(t *testing.T) { }{ { name: "short ciphertext", - data: []byte("short"), + data: make([]byte, 23), // Less than nonce size key: key, errMsg: "ciphertext too short", }, { name: "invalid ciphertext", - data: make([]byte, 16), // just nonce size + data: make([]byte, 24), // Just nonce size key: key, - errMsg: "message authentication failed", + errMsg: "decryption failed", + }, + { + name: "tampered ciphertext", + data: tamperWithBytes(encrypted), + key: key, + errMsg: "decryption failed", }, { name: "missing key", - data: []byte("�`M���l\u001AIF�\u0012���=h�?�c� ��\u0012����\u001C�\u0018Ƽ(g"), + data: encrypted, key: nil, errMsg: "encryption key is required", }, @@ -116,9 +125,20 @@ func TestDecryptionErrors(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - _, err := DecryptStringWithAESKey(tt.data, tt.key) + _, err := DecryptStringWithKey(tt.data, tt.key) require.Error(t, err) require.Contains(t, err.Error(), tt.errMsg) }) } } + +// tamperWithBytes modifies a byte in the encrypted data to simulate tampering +func tamperWithBytes(data []byte) []byte { + if len(data) < 25 { // Need at least nonce + 1 byte + return data + } + tampered := make([]byte, len(data)) + copy(tampered, data) + tampered[24] ^= 0x01 // Modify first byte after nonce + return tampered +} diff --git a/pkg/meta/meta.go b/pkg/meta/meta.go index 3c54738..21d56a6 100644 --- a/pkg/meta/meta.go +++ b/pkg/meta/meta.go @@ -63,7 +63,7 @@ func (m *Meta) GetEncryptedString(key string, encryptionKey []byte) (string, err return "", err } - decrypted, err := crypto.DecryptStringWithAESKey(v, encryptionKey) + decrypted, err := crypto.DecryptStringWithKey(v, encryptionKey) if err != nil { return "", err } @@ -111,7 +111,7 @@ func (m *Meta) GetEncryptedBytes(key string, encryptionKey []byte) ([]byte, erro return nil, err } - decrypted, err := crypto.DecryptStringWithAESKey(v, encryptionKey) + decrypted, err := crypto.DecryptStringWithKey(v, encryptionKey) if err != nil { return nil, err } @@ -156,12 +156,12 @@ func (m *Meta) AddEncrypted(key string, val any, encryptionKey []byte) error { switch val := val.(type) { case string: - encrypted, err = crypto.EncryptWithAESKey([]byte(val), encryptionKey) + encrypted, err = crypto.EncryptWithKey([]byte(val), encryptionKey) if err != nil { return err } case []byte: - encrypted, err = crypto.EncryptWithAESKey(val, encryptionKey) + encrypted, err = crypto.EncryptWithKey(val, encryptionKey) if err != nil { return err } From 200d6a8ae25563ffb3250021ad9a1a2310ba8dbe Mon Sep 17 00:00:00 2001 From: Fabio Bozzo Date: Thu, 28 Nov 2024 17:17:10 +0100 Subject: [PATCH 2/3] benchmarks vs aes-gcm --- pkg/meta/internal/crypto/secretbox_test.go | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/pkg/meta/internal/crypto/secretbox_test.go b/pkg/meta/internal/crypto/secretbox_test.go index d87f860..09d3831 100644 --- a/pkg/meta/internal/crypto/secretbox_test.go +++ b/pkg/meta/internal/crypto/secretbox_test.go @@ -2,7 +2,12 @@ package crypto import ( "bytes" + "crypto/aes" + "crypto/cipher" "crypto/rand" + "errors" + "fmt" + "io" "testing" "github.com/stretchr/testify/require" @@ -142,3 +147,147 @@ func tamperWithBytes(data []byte) []byte { tampered[24] ^= 0x01 // Modify first byte after nonce return tampered } + +func encryptWithAESKey(data, key []byte) ([]byte, error) { + if err := validateKey(key); err != nil { + return nil, err + } + + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + nonce := make([]byte, aesGCM.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return nil, err + } + + return aesGCM.Seal(nonce, nonce, data, nil), nil +} + +func decryptWithAESKey(data, key []byte) ([]byte, error) { + if err := validateKey(key); err != nil { + return nil, err + } + + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + nonceSize := aesGCM.NonceSize() + if len(data) < nonceSize { + return nil, ErrShortCipherText + } + + nonce, ciphertext := data[:nonceSize], data[nonceSize:] + plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil) + if err != nil { + return nil, errors.New("decryption failed") + } + + return plaintext, nil +} + +func BenchmarkEncryption(b *testing.B) { + key := make([]byte, keySize) + _, err := rand.Read(key) + require.NoError(b, err) + + sizes := []int{16, 64, 256, 1024, 4096} // Test different payload sizes + for _, size := range sizes { + data := make([]byte, size) + _, err := rand.Read(data) + require.NoError(b, err) + + b.Run(fmt.Sprintf("Secretbox-%dB", size), func(b *testing.B) { + for i := 0; i < b.N; i++ { + encrypted, err := EncryptWithKey(data, key) + require.NoError(b, err) + b.SetBytes(int64(len(encrypted))) + } + }) + + b.Run(fmt.Sprintf("AES-GCM-%dB", size), func(b *testing.B) { + for i := 0; i < b.N; i++ { + encrypted, err := encryptWithAESKey(data, key) + require.NoError(b, err) + b.SetBytes(int64(len(encrypted))) + } + }) + } +} + +func BenchmarkDecryption(b *testing.B) { + key := make([]byte, keySize) + _, err := rand.Read(key) + require.NoError(b, err) + + sizes := []int{16, 64, 256, 1024, 4096} + for _, size := range sizes { + data := make([]byte, size) + _, err := rand.Read(data) + require.NoError(b, err) + + secretboxEncrypted, err := EncryptWithKey(data, key) + require.NoError(b, err) + + aesGCMEncrypted, err := encryptWithAESKey(data, key) + require.NoError(b, err) + + b.Run(fmt.Sprintf("Secretbox-%dB", size), func(b *testing.B) { + for i := 0; i < b.N; i++ { + decrypted, err := DecryptStringWithKey(secretboxEncrypted, key) + require.NoError(b, err) + b.SetBytes(int64(len(decrypted))) + } + }) + + b.Run(fmt.Sprintf("AES-GCM-%dB", size), func(b *testing.B) { + for i := 0; i < b.N; i++ { + decrypted, err := decryptWithAESKey(aesGCMEncrypted, key) + require.NoError(b, err) + b.SetBytes(int64(len(decrypted))) + } + }) + } +} + +// TestCiphertextSizeComparison shows that Secretbox encryption entails +// a slightly larger ciphertext overhead of 40 bytes, compared to AES-GCM, +// whose overhead is just 28 bytes. +func TestCiphertextSizeComparison(t *testing.T) { + key := make([]byte, keySize) + _, err := rand.Read(key) + require.NoError(t, err) + + sizes := []int{0, 16, 64, 256, 1024, 4096} + for _, size := range sizes { + t.Run(fmt.Sprintf("size-%d", size), func(t *testing.T) { + data := make([]byte, size) + _, err := rand.Read(data) + require.NoError(t, err) + + sbCiphertext, err := EncryptWithKey(data, key) + require.NoError(t, err) + + aesCiphertext, err := encryptWithAESKey(data, key) + require.NoError(t, err) + + t.Logf("Input size: %d bytes", size) + t.Logf("Secretbox size: %d bytes (overhead: %d bytes)", len(sbCiphertext), len(sbCiphertext)-size) + t.Logf("AES-GCM size: %d bytes (overhead: %d bytes)", len(aesCiphertext), len(aesCiphertext)-size) + }) + } +} From 64d3024dec1693833255182332461394bb973b4a Mon Sep 17 00:00:00 2001 From: Fabio Bozzo Date: Mon, 2 Dec 2024 17:31:19 +0100 Subject: [PATCH 3/3] remove aes comparison and add ciphertext overhead comments --- pkg/meta/internal/crypto/secretbox.go | 3 +- pkg/meta/internal/crypto/secretbox_test.go | 149 --------------------- pkg/meta/meta.go | 1 + token/delegation/options.go | 6 +- 4 files changed, 7 insertions(+), 152 deletions(-) diff --git a/pkg/meta/internal/crypto/secretbox.go b/pkg/meta/internal/crypto/secretbox.go index 70d223c..690be7e 100644 --- a/pkg/meta/internal/crypto/secretbox.go +++ b/pkg/meta/internal/crypto/secretbox.go @@ -25,7 +25,8 @@ func GenerateKey() ([]byte, error) { return key, nil } -// EncryptWithKey encrypts data using secretbox with the provided key +// EncryptWithKey encrypts data using NaCl's secretbox with the provided key. +// 40 bytes of overhead (24-byte nonce + 16-byte MAC) are added to the plaintext size. func EncryptWithKey(data, key []byte) ([]byte, error) { if err := validateKey(key); err != nil { return nil, err diff --git a/pkg/meta/internal/crypto/secretbox_test.go b/pkg/meta/internal/crypto/secretbox_test.go index 09d3831..d87f860 100644 --- a/pkg/meta/internal/crypto/secretbox_test.go +++ b/pkg/meta/internal/crypto/secretbox_test.go @@ -2,12 +2,7 @@ package crypto import ( "bytes" - "crypto/aes" - "crypto/cipher" "crypto/rand" - "errors" - "fmt" - "io" "testing" "github.com/stretchr/testify/require" @@ -147,147 +142,3 @@ func tamperWithBytes(data []byte) []byte { tampered[24] ^= 0x01 // Modify first byte after nonce return tampered } - -func encryptWithAESKey(data, key []byte) ([]byte, error) { - if err := validateKey(key); err != nil { - return nil, err - } - - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - aesGCM, err := cipher.NewGCM(block) - if err != nil { - return nil, err - } - - nonce := make([]byte, aesGCM.NonceSize()) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - return nil, err - } - - return aesGCM.Seal(nonce, nonce, data, nil), nil -} - -func decryptWithAESKey(data, key []byte) ([]byte, error) { - if err := validateKey(key); err != nil { - return nil, err - } - - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - aesGCM, err := cipher.NewGCM(block) - if err != nil { - return nil, err - } - - nonceSize := aesGCM.NonceSize() - if len(data) < nonceSize { - return nil, ErrShortCipherText - } - - nonce, ciphertext := data[:nonceSize], data[nonceSize:] - plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil) - if err != nil { - return nil, errors.New("decryption failed") - } - - return plaintext, nil -} - -func BenchmarkEncryption(b *testing.B) { - key := make([]byte, keySize) - _, err := rand.Read(key) - require.NoError(b, err) - - sizes := []int{16, 64, 256, 1024, 4096} // Test different payload sizes - for _, size := range sizes { - data := make([]byte, size) - _, err := rand.Read(data) - require.NoError(b, err) - - b.Run(fmt.Sprintf("Secretbox-%dB", size), func(b *testing.B) { - for i := 0; i < b.N; i++ { - encrypted, err := EncryptWithKey(data, key) - require.NoError(b, err) - b.SetBytes(int64(len(encrypted))) - } - }) - - b.Run(fmt.Sprintf("AES-GCM-%dB", size), func(b *testing.B) { - for i := 0; i < b.N; i++ { - encrypted, err := encryptWithAESKey(data, key) - require.NoError(b, err) - b.SetBytes(int64(len(encrypted))) - } - }) - } -} - -func BenchmarkDecryption(b *testing.B) { - key := make([]byte, keySize) - _, err := rand.Read(key) - require.NoError(b, err) - - sizes := []int{16, 64, 256, 1024, 4096} - for _, size := range sizes { - data := make([]byte, size) - _, err := rand.Read(data) - require.NoError(b, err) - - secretboxEncrypted, err := EncryptWithKey(data, key) - require.NoError(b, err) - - aesGCMEncrypted, err := encryptWithAESKey(data, key) - require.NoError(b, err) - - b.Run(fmt.Sprintf("Secretbox-%dB", size), func(b *testing.B) { - for i := 0; i < b.N; i++ { - decrypted, err := DecryptStringWithKey(secretboxEncrypted, key) - require.NoError(b, err) - b.SetBytes(int64(len(decrypted))) - } - }) - - b.Run(fmt.Sprintf("AES-GCM-%dB", size), func(b *testing.B) { - for i := 0; i < b.N; i++ { - decrypted, err := decryptWithAESKey(aesGCMEncrypted, key) - require.NoError(b, err) - b.SetBytes(int64(len(decrypted))) - } - }) - } -} - -// TestCiphertextSizeComparison shows that Secretbox encryption entails -// a slightly larger ciphertext overhead of 40 bytes, compared to AES-GCM, -// whose overhead is just 28 bytes. -func TestCiphertextSizeComparison(t *testing.T) { - key := make([]byte, keySize) - _, err := rand.Read(key) - require.NoError(t, err) - - sizes := []int{0, 16, 64, 256, 1024, 4096} - for _, size := range sizes { - t.Run(fmt.Sprintf("size-%d", size), func(t *testing.T) { - data := make([]byte, size) - _, err := rand.Read(data) - require.NoError(t, err) - - sbCiphertext, err := EncryptWithKey(data, key) - require.NoError(t, err) - - aesCiphertext, err := encryptWithAESKey(data, key) - require.NoError(t, err) - - t.Logf("Input size: %d bytes", size) - t.Logf("Secretbox size: %d bytes (overhead: %d bytes)", len(sbCiphertext), len(sbCiphertext)-size) - t.Logf("AES-GCM size: %d bytes (overhead: %d bytes)", len(aesCiphertext), len(aesCiphertext)-size) - }) - } -} diff --git a/pkg/meta/meta.go b/pkg/meta/meta.go index 21d56a6..9b0e79f 100644 --- a/pkg/meta/meta.go +++ b/pkg/meta/meta.go @@ -150,6 +150,7 @@ func (m *Meta) Add(key string, val any) error { // AddEncrypted adds a key/value pair in the meta set. // The value is encrypted with the given encryptionKey. // Accepted types for the value are: string, []byte. +// The ciphertext will be 40 bytes larger than the plaintext due to encryption overhead. func (m *Meta) AddEncrypted(key string, val any, encryptionKey []byte) error { var encrypted []byte var err error diff --git a/token/delegation/options.go b/token/delegation/options.go index 4df14e7..3348760 100644 --- a/token/delegation/options.go +++ b/token/delegation/options.go @@ -45,7 +45,8 @@ func WithMeta(key string, val any) Option { } // WithEncryptedMetaString adds a key/value pair in the "meta" field. -// The string value is encrypted with the given aesKey. +// The string value is encrypted with the given key. +// The ciphertext will be 40 bytes larger than the plaintext due to encryption overhead. func WithEncryptedMetaString(key, val string, encryptionKey []byte) Option { return func(t *Token) error { return t.meta.AddEncrypted(key, val, encryptionKey) @@ -53,7 +54,8 @@ func WithEncryptedMetaString(key, val string, encryptionKey []byte) Option { } // WithEncryptedMetaBytes adds a key/value pair in the "meta" field. -// The []byte value is encrypted with the given aesKey. +// The []byte value is encrypted with the given key. +// The ciphertext will be 40 bytes larger than the plaintext due to encryption overhead. func WithEncryptedMetaBytes(key string, val, encryptionKey []byte) Option { return func(t *Token) error { return t.meta.AddEncrypted(key, val, encryptionKey)