From ff9f97f2ac9acbbcfbe4f0d92e53d299ab3c9b33 Mon Sep 17 00:00:00 2001 From: bizk Date: Fri, 24 Feb 2023 15:46:16 -0300 Subject: [PATCH 1/4] Replaced bcrypt.GenerateFromPassword for pdkdf2 module --- crypto/keys/keyring.go | 10 ++--- crypto/keys/mintkey/mintkey.go | 19 ++++----- crypto/keys/mintkey/mintkey_bench_test.go | 7 ++-- go.mod | 6 ++- go.sum | 49 +++++++++++++++++++++++ 5 files changed, 69 insertions(+), 22 deletions(-) diff --git a/crypto/keys/keyring.go b/crypto/keys/keyring.go index 3a6161f4f90d..c4891b3744e8 100644 --- a/crypto/keys/keyring.go +++ b/crypto/keys/keyring.go @@ -2,6 +2,7 @@ package keys import ( "bufio" + "crypto/sha256" "fmt" "io" "io/ioutil" @@ -24,6 +25,8 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" "github.com/cosmos/cosmos-sdk/crypto/keys/mintkey" "github.com/cosmos/cosmos-sdk/types" + + pdkdf2 "golang.org/x/crypto/pbkdf2" ) var _ Keybase = keyringKeybase{} @@ -519,11 +522,8 @@ func lkbToKeyringConfig(name, dir string, buf io.Reader, test bool) keyring.Conf } saltBytes := crypto.CRandBytes(16) - passwordHash, err := bcrypt.GenerateFromPassword(saltBytes, []byte(pass), 2) - if err != nil { - fmt.Fprintln(os.Stderr, err) - continue - } + + passwordHash := pdkdf2.Key([]byte(pass), saltBytes, 10, 24, sha256.New) if err := ioutil.WriteFile(dir+"/keyhash", passwordHash, 0555); err != nil { return "", err diff --git a/crypto/keys/mintkey/mintkey.go b/crypto/keys/mintkey/mintkey.go index 6b3a3af8ad4a..52bf3d071662 100644 --- a/crypto/keys/mintkey/mintkey.go +++ b/crypto/keys/mintkey/mintkey.go @@ -1,19 +1,18 @@ package mintkey import ( + "crypto/sha256" "encoding/hex" "fmt" - "github.com/tendermint/crypto/bcrypt" - "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/armor" cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/crypto/xsalsa20symmetric" - cmn "github.com/tendermint/tendermint/libs/common" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" + + pdkdf2 "golang.org/x/crypto/pbkdf2" ) const ( @@ -106,10 +105,8 @@ func EncryptArmorPrivKey(privKey crypto.PrivKey, passphrase string) string { // encrypted priv key. func encryptPrivKey(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte) { saltBytes = crypto.CRandBytes(16) - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BcryptSecurityParameter) - if err != nil { - cmn.Exit("Error generating bcrypt key from passphrase: " + err.Error()) - } + key := pdkdf2.Key([]byte(passphrase), saltBytes, BcryptSecurityParameter, 24, sha256.New) + key = crypto.Sha256(key) // get 32 bytes privKeyBytes := privKey.Bytes() return saltBytes, xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key) @@ -140,10 +137,8 @@ func UnarmorDecryptPrivKey(armorStr string, passphrase string) (crypto.PrivKey, } func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BcryptSecurityParameter) - if err != nil { - cmn.Exit("error generating bcrypt key from passphrase: " + err.Error()) - } + key := pdkdf2.Key([]byte(passphrase), saltBytes, BcryptSecurityParameter, 24, sha256.New) + key = crypto.Sha256(key) // Get 32 bytes privKeyBytes, err := xsalsa20symmetric.DecryptSymmetric(encBytes, key) if err != nil && err.Error() == "Ciphertext decryption failed" { diff --git a/crypto/keys/mintkey/mintkey_bench_test.go b/crypto/keys/mintkey/mintkey_bench_test.go index 1dd0b36cb373..27b817037e49 100644 --- a/crypto/keys/mintkey/mintkey_bench_test.go +++ b/crypto/keys/mintkey/mintkey_bench_test.go @@ -1,13 +1,14 @@ package mintkey import ( + "crypto/sha256" "fmt" "testing" "github.com/stretchr/testify/require" - "github.com/tendermint/crypto/bcrypt" "github.com/tendermint/tendermint/crypto" + pdkdf2 "golang.org/x/crypto/pbkdf2" ) func BenchmarkBcryptGenerateFromPassword(b *testing.B) { @@ -18,8 +19,8 @@ func BenchmarkBcryptGenerateFromPassword(b *testing.B) { saltBytes := crypto.CRandBytes(16) b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := bcrypt.GenerateFromPassword(saltBytes, passphrase, param) - require.Nil(b, err) + key := pdkdf2.Key([]byte(passphrase), saltBytes, param, 24, sha256.New) + require.NotNil(b, key) } }) } diff --git a/go.mod b/go.mod index 1a2c517c92ce..8c49f7a87979 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/cosmos/cosmos-sdk require ( - github.com/99designs/keyring v1.1.2 + github.com/99designs/keyring v1.2.2 github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d github.com/bgentry/speakeasy v0.1.0 github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d @@ -11,6 +11,7 @@ require ( github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 github.com/gorilla/mux v1.7.3 github.com/hashicorp/golang-lru v0.5.3 + github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect github.com/mattn/go-isatty v0.0.10 github.com/pelletier/go-toml v1.5.0 github.com/pkg/errors v0.8.1 @@ -20,7 +21,7 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.4.0 - github.com/stretchr/testify v1.4.0 + github.com/stretchr/testify v1.7.0 github.com/stumble/gorocksdb v0.0.3 // indirect github.com/tendermint/btcd v0.1.1 github.com/tendermint/crypto v0.0.0-20190823183015-45b1026d81ae @@ -28,6 +29,7 @@ require ( github.com/tendermint/iavl v0.12.4 github.com/tendermint/tendermint v0.32.6 github.com/tendermint/tm-db v0.2.0 + golang.org/x/crypto v0.6.0 // indirect gopkg.in/yaml.v2 v2.2.4 ) diff --git a/go.sum b/go.sum index 49d59bba05ef..e45792bccfbe 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.1.2 h1:JJauROcU6x6Nh9uZb+8JgXFvyo0GUESLo1ixhpA0Kmw= github.com/99designs/keyring v1.1.2/go.mod h1:657DQuMrBZRtuL/voxVyiyb6zpMehlm5vLB9Qwrv904= +github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -46,6 +50,8 @@ github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -54,6 +60,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a h1:mq+R6XEM6lJX5VlLyZIrUSP8tSuJp82xTK89hvBwJbU= github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/etcd-io/bbolt v1.3.2/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= @@ -159,7 +167,10 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= @@ -226,10 +237,14 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stumble/gorocksdb v0.0.3 h1:9UU+QA1pqFYJuf9+5p7z1IqdE5k0mma4UAeu2wmX8kA= github.com/stumble/gorocksdb v0.0.3/go.mod h1:v6IHdFBXk5DJ1K4FZ0xi+eY737quiiBxYtSWXadLybY= github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw= @@ -255,6 +270,7 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -272,8 +288,12 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exq golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -281,14 +301,19 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -300,15 +325,35 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -326,6 +371,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -337,5 +384,7 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 8f7e34b55ec3c4816b0d5b4bea504a4021110b4e Mon Sep 17 00:00:00 2001 From: bizk Date: Mon, 27 Feb 2023 17:51:48 -0300 Subject: [PATCH 2/4] Added testing for new bcrypt api usage and changed generated key byte size to 60 --- crypto/keys/keyring.go | 2 +- crypto/keys/keyring_test.go | 24 ++++++++++++++++++++++++ go.sum | 3 +++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/crypto/keys/keyring.go b/crypto/keys/keyring.go index c4891b3744e8..293f8beaa35e 100644 --- a/crypto/keys/keyring.go +++ b/crypto/keys/keyring.go @@ -523,7 +523,7 @@ func lkbToKeyringConfig(name, dir string, buf io.Reader, test bool) keyring.Conf saltBytes := crypto.CRandBytes(16) - passwordHash := pdkdf2.Key([]byte(pass), saltBytes, 10, 24, sha256.New) + passwordHash := pdkdf2.Key([]byte(pass), saltBytes, 10, 60, sha256.New) if err := ioutil.WriteFile(dir+"/keyhash", passwordHash, 0555); err != nil { return "", err diff --git a/crypto/keys/keyring_test.go b/crypto/keys/keyring_test.go index 0916e0f46e9e..3df2562c3899 100644 --- a/crypto/keys/keyring_test.go +++ b/crypto/keys/keyring_test.go @@ -2,12 +2,16 @@ package keys import ( + "crypto/sha256" + "fmt" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tendermint/crypto/bcrypt" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + pdkdf2 "golang.org/x/crypto/pbkdf2" "github.com/cosmos/cosmos-sdk/crypto/keys/hd" "github.com/cosmos/cosmos-sdk/tests" @@ -323,3 +327,23 @@ func TestLazySeedPhraseKeyRing(t *testing.T) { require.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address()) require.Equal(t, info.GetPubKey(), newInfo.GetPubKey()) } + +func TestKeyDerivation(t *testing.T) { + passPhrase := "RandomPassPhrase" + saltBytes := crypto.CRandBytes(16) + + oldDerivedKey, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passPhrase), 2) + assert.NotEmpty(t, oldDerivedKey) + require.NotNil(t, oldDerivedKey) + require.Equal(t, 60, len(oldDerivedKey)) + require.NoError(t, err) + + derivedKey := pdkdf2.Key([]byte(passPhrase), saltBytes, 10, 60, sha256.New) + assert.NotEmpty(t, derivedKey) + require.NotNil(t, derivedKey) + require.Equal(t, 60, len(derivedKey)) + + fmt.Println("the derivation key is", derivedKey, len(derivedKey), string(derivedKey)) + + // fmt.Println("the old derivation key is", oldDerivedKey, len(oldDerivedKey), string(oldDerivedKey)) +} diff --git a/go.sum b/go.sum index e45792bccfbe..9d721c3e0a11 100644 --- a/go.sum +++ b/go.sum @@ -306,6 +306,7 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8 golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -342,6 +343,7 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -385,6 +387,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 8ea1c4bf743d2f0ccddd632da5e18554af2409d8 Mon Sep 17 00:00:00 2001 From: bizk Date: Mon, 27 Feb 2023 17:52:30 -0300 Subject: [PATCH 3/4] removed unnecesary logging on tests --- crypto/keys/keyring_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crypto/keys/keyring_test.go b/crypto/keys/keyring_test.go index 3df2562c3899..547d9128d146 100644 --- a/crypto/keys/keyring_test.go +++ b/crypto/keys/keyring_test.go @@ -3,7 +3,6 @@ package keys import ( "crypto/sha256" - "fmt" "testing" "github.com/stretchr/testify/assert" @@ -342,8 +341,4 @@ func TestKeyDerivation(t *testing.T) { assert.NotEmpty(t, derivedKey) require.NotNil(t, derivedKey) require.Equal(t, 60, len(derivedKey)) - - fmt.Println("the derivation key is", derivedKey, len(derivedKey), string(derivedKey)) - - // fmt.Println("the old derivation key is", oldDerivedKey, len(oldDerivedKey), string(oldDerivedKey)) } From 617085e39d946dffa17439a441102726b90d1ed9 Mon Sep 17 00:00:00 2001 From: bizk Date: Wed, 1 Mar 2023 10:50:38 -0300 Subject: [PATCH 4/4] Added tests and reorganized legacy code --- crypto/keys/keyring.go | 9 +++-- crypto/keys/mintkey/mintkey.go | 51 +++++++++++++++++++++++------ crypto/keys/mintkey/mintkey_test.go | 38 +++++++++++++++++++++ 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/crypto/keys/keyring.go b/crypto/keys/keyring.go index 293f8beaa35e..ab5bf3191117 100644 --- a/crypto/keys/keyring.go +++ b/crypto/keys/keyring.go @@ -2,6 +2,7 @@ package keys import ( "bufio" + "crypto/hmac" "crypto/sha256" "fmt" "io" @@ -523,9 +524,13 @@ func lkbToKeyringConfig(name, dir string, buf io.Reader, test bool) keyring.Conf saltBytes := crypto.CRandBytes(16) - passwordHash := pdkdf2.Key([]byte(pass), saltBytes, 10, 60, sha256.New) + //Create a password hash with MAC to differentiate old bcrypt.GeneratePassword from pdkdf2 + mac := hmac.New(sha256.New, []byte(pass)) + passwordHash := pdkdf2.Key([]byte(pass), saltBytes, 4096, 60, sha256.New) + mac.Write(passwordHash) + passwordHashMac := mac.Sum(nil) - if err := ioutil.WriteFile(dir+"/keyhash", passwordHash, 0555); err != nil { + if err := ioutil.WriteFile(dir+"/keyhash", passwordHashMac, 0555); err != nil { return "", err } diff --git a/crypto/keys/mintkey/mintkey.go b/crypto/keys/mintkey/mintkey.go index 52bf3d071662..575fb08dbcb4 100644 --- a/crypto/keys/mintkey/mintkey.go +++ b/crypto/keys/mintkey/mintkey.go @@ -1,17 +1,20 @@ package mintkey import ( + "bytes" "crypto/sha256" "encoding/hex" "fmt" + "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/armor" cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/crypto/xsalsa20symmetric" - "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" + cmn "github.com/tendermint/tendermint/libs/common" + "github.com/tendermint/crypto/bcrypt" pdkdf2 "golang.org/x/crypto/pbkdf2" ) @@ -105,10 +108,11 @@ func EncryptArmorPrivKey(privKey crypto.PrivKey, passphrase string) string { // encrypted priv key. func encryptPrivKey(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte) { saltBytes = crypto.CRandBytes(16) - key := pdkdf2.Key([]byte(passphrase), saltBytes, BcryptSecurityParameter, 24, sha256.New) - + key := pdkdf2.Key([]byte(passphrase), saltBytes, BcryptSecurityParameter, 60, sha256.New) key = crypto.Sha256(key) // get 32 bytes privKeyBytes := privKey.Bytes() + privKeyBytesHash := crypto.Sha256(privKeyBytes) + privKeyBytes = append(privKeyBytes, privKeyBytesHash...) // Add own hash to differentiate it from old implementation return saltBytes, xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key) } @@ -137,15 +141,42 @@ func UnarmorDecryptPrivKey(armorStr string, passphrase string) (crypto.PrivKey, } func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { - key := pdkdf2.Key([]byte(passphrase), saltBytes, BcryptSecurityParameter, 24, sha256.New) - + key := pdkdf2.Key([]byte(passphrase), saltBytes, BcryptSecurityParameter, 60, sha256.New) key = crypto.Sha256(key) // Get 32 bytes - privKeyBytes, err := xsalsa20symmetric.DecryptSymmetric(encBytes, key) - if err != nil && err.Error() == "Ciphertext decryption failed" { - return privKey, keyerror.NewErrWrongPassword() - } else if err != nil { + + privateBytes, err := decryptSymmetric(encBytes, key) + if err == nil || len(privateBytes) > 32 { + decryptedBytes := privateBytes[:len(privateBytes)-32] + decryptedBytesHash := privateBytes[len(privateBytes)-32:] //SHA-256 hash is 32 bytes + //If the decrypted hash doesn't match the privateBytes hash, then we are working with the old bcrypt algorithm + if !bytes.Equal(crypto.Sha256(decryptedBytes), decryptedBytesHash) { + decryptedBytes, err = decryptPrivKeyLegacy(saltBytes, encBytes, passphrase) + } + } else { + privateBytes, err = decryptPrivKeyLegacy(saltBytes, encBytes, passphrase) + } + + if err != nil { return privKey, err } - privKey, err = cryptoAmino.PrivKeyFromBytes(privKeyBytes) + privKey, err = cryptoAmino.PrivKeyFromBytes(privateBytes) return privKey, err } + +func decryptPrivKeyLegacy(saltBytes []byte, encBytes []byte, passphrase string) (decryptedBytes []byte, err error) { + key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BcryptSecurityParameter) + if err != nil { + cmn.Exit("error generating bcrypt key from passphrase: " + err.Error()) + } + return decryptSymmetric(encBytes, key) +} + +func decryptSymmetric(encBytes []byte, key []byte) (decryptedBytes []byte, err error) { + decryptedBytes, err = xsalsa20symmetric.DecryptSymmetric(encBytes, key) + if err != nil && err.Error() == "Ciphertext decryption failed" { + return decryptedBytes, keyerror.NewErrWrongPassword() + } else if err != nil { + return decryptedBytes, err + } + return decryptedBytes, nil +} diff --git a/crypto/keys/mintkey/mintkey_test.go b/crypto/keys/mintkey/mintkey_test.go index b4ce4d6a0f20..53be95e50d03 100644 --- a/crypto/keys/mintkey/mintkey_test.go +++ b/crypto/keys/mintkey/mintkey_test.go @@ -1,11 +1,16 @@ package mintkey_test import ( + "fmt" "testing" "github.com/stretchr/testify/require" + "github.com/tendermint/crypto/bcrypt" + "github.com/tendermint/tendermint/crypto" + armor "github.com/tendermint/tendermint/crypto/armor" cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/crypto/secp256k1" + "github.com/tendermint/tendermint/crypto/xsalsa20symmetric" "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/crypto/keys/mintkey" @@ -35,3 +40,36 @@ func TestArmorUnarmorPubKey(t *testing.T) { require.NoError(t, err) require.True(t, pub.Equals(info.GetPubKey())) } + +func TestPdkdf2Encryption(t *testing.T) { + priv := secp256k1.GenPrivKey() + armor := mintkey.EncryptArmorPrivKey(priv, "passphrase") + _, err := mintkey.UnarmorDecryptPrivKey(armor, "wrongpassphrase") + require.Error(t, err) + decrypted, err := mintkey.UnarmorDecryptPrivKey(armor, "passphrase") + require.NoError(t, err) + require.True(t, priv.Equals(decrypted)) + require.Equal(t, priv, decrypted) +} + +func TestBcryptLegacyEncryption(t *testing.T) { + priv := secp256k1.GenPrivKey() + + saltBytes := crypto.CRandBytes(16) + key, _ := bcrypt.GenerateFromPassword(saltBytes, []byte("passphrase"), 12) + key = crypto.Sha256(key) // get 32 bytes + privKeyBytes := priv.Bytes() + encBytes := xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key) + header := map[string]string{ + "kdf": "bcrypt", + "salt": fmt.Sprintf("%X", saltBytes), + } + armorString := armor.EncodeArmor("TENDERMINT PRIVATE KEY", header, encBytes) + + _, err := mintkey.UnarmorDecryptPrivKey(armorString, "wrongpassphrase") + require.Error(t, err) + decrypted, err := mintkey.UnarmorDecryptPrivKey(armorString, "passphrase") + require.NoError(t, err) + require.True(t, priv.Equals(decrypted)) + require.Equal(t, priv, decrypted) +}