diff options
| author | Levi Durfee <levi.durfee@gmail.com> | 2026-01-07 11:35:07 -0500 |
|---|---|---|
| committer | Levi Durfee <levi.durfee@gmail.com> | 2026-01-07 11:45:18 -0500 |
| commit | ac5b030f71434123bea60f9b1d918a59f19fed6a (patch) | |
| tree | 4472e5c976692c20e68218eb9fe6a56cee201d1c | |
| parent | b1f9ade1154df9353f19141d3ca719a8bb7936e8 (diff) | |
Switch to argon2
| -rw-r--r-- | cmd/goaes/commands/decrypt.go | 2 | ||||
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | go.sum | 2 | ||||
| -rw-r--r-- | internal/decrypt.go | 4 | ||||
| -rw-r--r-- | internal/encrypt.go | 3 | ||||
| -rw-r--r-- | internal/goaes.go | 40 | ||||
| -rw-r--r-- | internal/internal.go | 2 |
7 files changed, 33 insertions, 22 deletions
diff --git a/cmd/goaes/commands/decrypt.go b/cmd/goaes/commands/decrypt.go index f5f5dba..8f73c42 100644 --- a/cmd/goaes/commands/decrypt.go +++ b/cmd/goaes/commands/decrypt.go @@ -34,7 +34,7 @@ func Decrypt(ctx context.Context, cmd *cli.Command) error { return err } - plaintext, err := internal.Decrypt(encryptedPayload.DEK, encryptedPayload.Payload) + plaintext, err := internal.Decrypt(encryptedPayload.DEK, encryptedPayload.Payload, encryptedPayload.Salt) if err != nil { return err } @@ -6,3 +6,5 @@ require ( github.com/urfave/cli/v3 v3.6.1 golang.org/x/crypto v0.46.0 ) + +require golang.org/x/sys v0.39.0 // indirect @@ -8,5 +8,7 @@ github.com/urfave/cli/v3 v3.6.1 h1:j8Qq8NyUawj/7rTYdBGrxcH7A/j7/G8Q5LhWEW4G3Mo= github.com/urfave/cli/v3 v3.6.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/decrypt.go b/internal/decrypt.go index 913201f..470e3c5 100644 --- a/internal/decrypt.go +++ b/internal/decrypt.go @@ -1,7 +1,7 @@ package internal -func Decrypt(edek WrappedDEK, ct Ciphertext) ([]byte, error) { - kek, err := NewKEKFromEnvB64("GOAES_PASSPHRASE", "GOAES_SALT") +func Decrypt(edek WrappedDEK, ct Ciphertext, salt Salt) ([]byte, error) { + kek, err := NewKEKFromEnvB64("GOAES_PASSPHRASE") if err != nil { return nil, err } diff --git a/internal/encrypt.go b/internal/encrypt.go index 204c6f2..3ee73d7 100644 --- a/internal/encrypt.go +++ b/internal/encrypt.go @@ -1,7 +1,7 @@ package internal func Encrypt(data []byte) (EncryptedDataPayload, error) { - kek, err := NewKEKFromEnvB64("GOAES_PASSPHRASE", "GOAES_SALT") + kek, salt, err := NewKEKFromEnvB64("GOAES_PASSPHRASE") if err != nil { return EncryptedDataPayload{}, err } @@ -23,6 +23,7 @@ func Encrypt(data []byte) (EncryptedDataPayload, error) { return EncryptedDataPayload{ DEK: edek, + Salt: salt, Payload: ct, }, nil } diff --git a/internal/goaes.go b/internal/goaes.go index 1923b8e..7d4f476 100644 --- a/internal/goaes.go +++ b/internal/goaes.go @@ -4,59 +4,63 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" - "crypto/sha256" "encoding/base64" "errors" "fmt" "io" "os" - "golang.org/x/crypto/pbkdf2" + "golang.org/x/crypto/argon2" ) const ( - keyIterations = 600_000 - keyLength = 32 + time = 3 + memory = 256 * 1024 + threads = 4 + keyLen = 32 ) -func NewKEKFromEnvB64(passphraseEnvVar, saltEnvVar string) (KEK, error) { +func NewKEKFromEnvB64(passphraseEnvVar string) (KEK, Salt, error) { b64Passphrase := os.Getenv(passphraseEnvVar) if b64Passphrase == "" { - return nil, fmt.Errorf("%s is not set", passphraseEnvVar) - } - - b64Salt := os.Getenv(saltEnvVar) - if b64Salt == "" { - return nil, fmt.Errorf("%s is not set", saltEnvVar) + return nil, nil, fmt.Errorf("%s is not set", passphraseEnvVar) } passphrase, err := base64.StdEncoding.DecodeString(b64Passphrase) if err != nil { - return nil, fmt.Errorf("decode %s base64: %w", passphraseEnvVar, err) + return nil, nil, fmt.Errorf("decode %s base64: %w", passphraseEnvVar, err) } - salt, err := base64.StdEncoding.DecodeString(b64Salt) + salt, err := NewSalt() if err != nil { - return nil, fmt.Errorf("decode %s base64: %w", saltEnvVar, err) + return nil, nil, fmt.Errorf("failed to create salt %w", err) } - raw := pbkdf2.Key(passphrase, salt, keyIterations, keyLength, sha256.New) + raw := argon2.IDKey(passphrase, salt, time, memory, threads, keyLen) if !validAESKeyLen(len(raw)) { - return nil, errBadKeyLn + return nil, nil, errBadKeyLn } - return KEK(raw), nil + return KEK(raw), Salt(salt), nil } func NewDEK() (DEK, error) { - key := make([]byte, 32) // AES-256 + key := make([]byte, 32) if _, err := io.ReadFull(rand.Reader, key); err != nil { return nil, fmt.Errorf("random DEK gen: %w", err) } return DEK(key), nil } +func NewSalt() (Salt, error) { + key := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + return nil, fmt.Errorf("random salt gen: %w", err) + } + return Salt(key), nil +} + func WrapDEK(dek DEK, kek KEK) (WrappedDEK, error) { edek, err := encryptAEAD([]byte(dek), []byte(kek), aadWrapDEK) return WrappedDEK(edek), err diff --git a/internal/internal.go b/internal/internal.go index 970232c..0a3bb54 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -7,10 +7,12 @@ type ( DEK []byte WrappedDEK []byte Ciphertext []byte + Salt []byte ) type EncryptedDataPayload struct { DEK WrappedDEK + Salt Salt Payload Ciphertext } |
