Skip to content

Commit

Permalink
Use constant parameters for argon key generation (#477)
Browse files Browse the repository at this point in the history
- Previously we were using `runtime.NumCPU()` as one of the parameters of `argon2.IDKey()`.
  If you encrypt something in one computer with 2cpus and then try to decrypt in another with 4cpus; you get an error:
  `panic: chacha20poly1305: message authentication failed`
- We have also now added the `ong/cry` version to the encryption/decryption additionalData.
   This ensures that encrypt/decrypt across different versions will fail.
  • Loading branch information
komuw authored Sep 16, 2024
1 parent 7088080 commit 424f53c
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 28 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
Most recent version is listed first.


# v0.1.11
- ong/cry: use constant parameters for argon key generation: https://github.com/komuw/ong/pull/477

# v0.1.10
- ong/cry: refactor aead implementation: https://github.com/komuw/ong/pull/476

Expand Down
2 changes: 1 addition & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const (
// In there we can see that the p95 response times for http GET requests is ~700ms: https://grafana.wikimedia.org/d/RIA1lzDZk/application-servers-red?orgId=1
// and the p95 response times for http POST requests is ~3seconds:
// Thus, we set the timeout to be twice that.
defaultTimeout = 3 * 2 * time.Second
defaultTimeout = 2 * 3 * time.Second
)

// Some of the code here is inspired by(or taken from):
Expand Down
17 changes: 5 additions & 12 deletions cry/enc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"encoding/base64"
"errors"
"fmt"
"runtime"
"slices"

"github.com/komuw/ong/internal/key"
Expand Down Expand Up @@ -38,15 +37,6 @@ const (
saltLen = 8
)

var (
//
// The values recommended are:
// golang.org/x/crypto/argon2
time = uint32(1) //nolint:gochecknoglobals
memory = uint32(64 * 1024) //nolint:gochecknoglobals // 64MB
threads = uint8(runtime.NumCPU()) //nolint:gochecknoglobals
)

// Enc is an AEAD cipher mode providing authenticated encryption with associated data, ie [cipher.AEAD]
//
// Use [New] to get a valid Enc.
Expand Down Expand Up @@ -120,7 +110,10 @@ func (e Enc) Encrypt(plainTextMsg string) (encryptedMsg []byte) {
)

// Encrypt the message and append the ciphertext to the nonce.
encrypted := e.aead.Seal(nonce, nonce, msgToEncrypt, nil)
//
// version as additionalData ensures that encryption/decryption will fail if using different versions of `ong/cry`
// another option would be to prepend the version similar to salt.
encrypted := e.aead.Seal(nonce, nonce, msgToEncrypt, []byte{version})

// Append the salt & nonce to encrypted msg.
// |salt|nonce|encryptedMsg|
Expand Down Expand Up @@ -161,7 +154,7 @@ func (e Enc) Decrypt(encryptedMsg []byte) (decryptedMsg []byte, err error) {
}

// Decrypt the message and check it wasn't tampered with.
return aead.Open(nil, nonce, ciphertext, nil)
return aead.Open(nil, nonce, ciphertext, []byte{version})
}

// EncryptEncode is like [Enc.Encrypt] except that it returns a string that is encoded using [base64.RawURLEncoding]
Expand Down
14 changes: 11 additions & 3 deletions cry/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@ import (
// (a) https://github.com/elithrar/simple-scrypt whose license(MIT) can be found here: https://github.com/elithrar/simple-scrypt/blob/v1.3.0/LICENSE

const (
// this should be increased every time the parameters passed to [argon2.IDKey] are changed.
version = 1
// this should be incremented every time the parameters passed to [argon2.IDKey] are changed.
version = 2
separator = "$"

// The values recommended are:
// golang.org/x/crypto/argon2
_time = uint32(1)
memory = uint32(64 * 1024) // 64MB
threads = uint8(2) // can be set to number of available CPUS. Can't use `runtime.NumCPU()` since that will be different between computers.
)

func deriveKey(password, salt []byte) []byte {
// IDKey is Argon2id
return argon2.IDKey(password, salt, time, memory, threads, keyLen)
return argon2.IDKey(password, salt, _time, memory, threads, keyLen)
}

// Hash returns the argon2id hash of the password.
Expand All @@ -33,6 +39,8 @@ func Hash(password string) string {

// Add version, salt to the derived key.
// The salt and the derived key are hex encoded.
// NB: We could include the other params(_time, memory, threads) in this serialization.
// But we don't for simplicity & also because those params are hardcoded for each `ong/cry` version.
return fmt.Sprintf(
`%d%s%x%s%x`,
version,
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module github.com/komuw/ong
go 1.23

require (
golang.org/x/crypto v0.26.0
golang.org/x/net v0.28.0
golang.org/x/sys v0.24.0
golang.org/x/crypto v0.27.0
golang.org/x/net v0.29.0
golang.org/x/sys v0.25.0
)

require (
Expand All @@ -19,7 +19,7 @@ require (
github.com/tmthrgd/httputils v0.0.0-20190904060602-27fdf7d93acd // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/text v0.18.0 // indirect
)

require (
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,24 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca h1:PupagGYwj8+I4ubCxcmcBRk3VlUWtTg5huQpZR9flmE=
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
Expand Down

0 comments on commit 424f53c

Please sign in to comment.