aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Simonsson <gustav.simonsson@gmail.com>2015-04-15 19:24:12 +0800
committerGustav Simonsson <gustav.simonsson@gmail.com>2015-05-12 23:19:39 +0800
commit29a5a92d13cad45794c6e42cb97260a9ab9900ab (patch)
treebfd1ce21673be3610f188a639518bd8e331a8d2e
parentac3371bcb69b090fa9b5a8da96916fa0aa15ed0f (diff)
downloaddexon-29a5a92d13cad45794c6e42cb97260a9ab9900ab.tar.gz
dexon-29a5a92d13cad45794c6e42cb97260a9ab9900ab.tar.zst
dexon-29a5a92d13cad45794c6e42cb97260a9ab9900ab.zip
Add key header to encrypted keys
* Add key header containing key version, kdf and kdf params * Store key header as JSON in the key file * Read in KDF params from key header * Include key header in MAC calculation and MAC verification
-rw-r--r--crypto/key.go23
-rw-r--r--crypto/key_store_passphrase.go41
2 files changed, 57 insertions, 7 deletions
diff --git a/crypto/key.go b/crypto/key.go
index 5e1f3637e..067a5a294 100644
--- a/crypto/key.go
+++ b/crypto/key.go
@@ -48,17 +48,32 @@ type plainKeyJSON struct {
PrivateKey []byte
}
+type encryptedKeyJSON struct {
+ Id []byte
+ Address []byte
+ Crypto cipherJSON
+}
+
type cipherJSON struct {
MAC []byte
Salt []byte
IV []byte
+ KeyHeader keyHeaderJSON
CipherText []byte
}
-type encryptedKeyJSON struct {
- Id []byte
- Address []byte
- Crypto cipherJSON
+type keyHeaderJSON struct {
+ Version string
+ Kdf string
+ KdfParams scryptParamsJSON // TODO: make more generic?
+}
+
+type scryptParamsJSON struct {
+ N int
+ R int
+ P int
+ DkLen int
+ SaltLen int
}
func (k *Key) MarshalJSON() (j []byte, err error) {
diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go
index 739483d9f..00717b5d1 100644
--- a/crypto/key_store_passphrase.go
+++ b/crypto/key_store_passphrase.go
@@ -81,6 +81,8 @@ import (
)
const (
+ keyHeaderVersion = "1"
+ keyHeaderKDF = "scrypt"
// 2^18 / 8 / 1 uses 256MB memory and approx 1s CPU time on a modern CPU.
scryptN = 1 << 18
scryptr = 8
@@ -140,12 +142,32 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) {
cipherText := make([]byte, len(toEncrypt))
AES128CBCEncrypter.CryptBlocks(cipherText, toEncrypt)
- mac := Sha3(derivedKey[16:32], cipherText)
+ paramsJSON := scryptParamsJSON{
+ N: scryptN,
+ R: scryptr,
+ P: scryptp,
+ DkLen: scryptdkLen,
+ SaltLen: 32,
+ }
+
+ keyHeaderJSON := keyHeaderJSON{
+ Version: keyHeaderVersion,
+ Kdf: keyHeaderKDF,
+ KdfParams: paramsJSON,
+ }
+
+ keyHeaderJSONStr, err := json.Marshal(keyHeaderJSON)
+ if err != nil {
+ return err
+ }
+
+ mac := Sha3(keyHeaderJSONStr, derivedKey[16:32], cipherText)
cipherStruct := cipherJSON{
mac,
salt,
iv,
+ keyHeaderJSON,
cipherText,
}
keyStruct := encryptedKeyJSON{
@@ -185,15 +207,28 @@ func DecryptKey(ks keyStorePassphrase, keyAddr common.Address, auth string) (key
mac := keyProtected.Crypto.MAC
salt := keyProtected.Crypto.Salt
iv := keyProtected.Crypto.IV
+ keyHeader := keyProtected.Crypto.KeyHeader
cipherText := keyProtected.Crypto.CipherText
+ // used in MAC
+ keyHeaderJSONStr, err := json.Marshal(keyHeader)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // TODO: make this more generic when we support different KDF params / key versions
+ n := keyHeader.KdfParams.N
+ r := keyHeader.KdfParams.R
+ p := keyHeader.KdfParams.P
+ dkLen := keyHeader.KdfParams.DkLen
+
authArray := []byte(auth)
- derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen)
+ derivedKey, err := scrypt.Key(authArray, salt, n, r, p, dkLen)
if err != nil {
return nil, nil, err
}
- calculatedMAC := Sha3(derivedKey[16:32], cipherText)
+ calculatedMAC := Sha3(keyHeaderJSONStr, derivedKey[16:32], cipherText)
if !bytes.Equal(calculatedMAC, mac) {
err = errors.New("Decryption failed: MAC mismatch")
return nil, nil, err