Address pull request comments; key header and hex encoding

* Remove key header from unencrypted key file format and replace
  it with a version field
* Change encoding of bytes in key files from base64 to hex
This commit is contained in:
Gustav Simonsson 2015-04-21 17:00:30 +02:00
parent 313eec33ad
commit f98e002d98
3 changed files with 67 additions and 31 deletions

View File

@ -26,6 +26,7 @@ package crypto
import (
"bytes"
"crypto/ecdsa"
"encoding/hex"
"encoding/json"
"io"
@ -33,6 +34,10 @@ import (
"github.com/ethereum/go-ethereum/common"
)
const (
version = "1"
)
type Key struct {
Id uuid.UUID // Version 4 "random" for unique id not derived from key data
// to simplify lookups we also store the address
@ -43,29 +48,31 @@ type Key struct {
}
type plainKeyJSON struct {
Id []byte
Address []byte
PrivateKey []byte
Version string
Id string
Address string
PrivateKey string
}
type encryptedKeyJSON struct {
Id []byte
Address []byte
Version string
Id string
Address string
Crypto cipherJSON
}
type cipherJSON struct {
MAC []byte
Salt []byte
IV []byte
MAC string
Salt string
IV string
KeyHeader keyHeaderJSON
CipherText []byte
CipherText string
}
type keyHeaderJSON struct {
Version string
Kdf string
KdfParams scryptParamsJSON // TODO: make more generic?
KdfParams scryptParamsJSON
}
type scryptParamsJSON struct {
@ -78,9 +85,10 @@ type scryptParamsJSON struct {
func (k *Key) MarshalJSON() (j []byte, err error) {
jStruct := plainKeyJSON{
k.Id,
k.Address.Bytes(),
FromECDSA(k.PrivateKey),
version,
k.Id.String(),
hex.EncodeToString(k.Address[:]),
hex.EncodeToString(FromECDSA(k.PrivateKey)),
}
j, err = json.Marshal(jStruct)
return j, err
@ -94,14 +102,24 @@ func (k *Key) UnmarshalJSON(j []byte) (err error) {
}
u := new(uuid.UUID)
*u = keyJSON.Id
*u = uuid.Parse(keyJSON.Id)
k.Id = *u
k.Address = common.BytesToAddress(keyJSON.Address)
k.PrivateKey = ToECDSA(keyJSON.PrivateKey)
addr, err := hex.DecodeString(keyJSON.Address)
if err != nil {
return err
}
privkey, err := hex.DecodeString(keyJSON.PrivateKey)
if err != nil {
return err
}
k.Address = common.BytesToAddress(addr)
k.PrivateKey = ToECDSA(privkey)
return nil
}
func NewKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key {
id := uuid.NewRandom()
key := &Key{

View File

@ -68,6 +68,7 @@ import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"encoding/json"
"errors"
"io"
@ -164,15 +165,16 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) {
mac := Sha3(keyHeaderJSONStr, derivedKey[16:32], cipherText)
cipherStruct := cipherJSON{
mac,
salt,
iv,
hex.EncodeToString(mac),
hex.EncodeToString(salt),
hex.EncodeToString(iv),
keyHeaderJSON,
cipherText,
hex.EncodeToString(cipherText),
}
keyStruct := encryptedKeyJSON{
key.Id,
key.Address.Bytes(),
version,
key.Id.String(),
hex.EncodeToString(key.Address[:]),
cipherStruct,
}
keyJSON, err := json.Marshal(keyStruct)
@ -190,7 +192,7 @@ func (ks keyStorePassphrase) DeleteKey(keyAddr common.Address, auth string) (err
return err
}
keyDirPath := filepath.Join(ks.keysDirPath, keyAddr.Hex())
keyDirPath := filepath.Join(ks.keysDirPath, hex.EncodeToString(keyAddr[:]))
return os.RemoveAll(keyDirPath)
}
@ -203,12 +205,28 @@ func DecryptKey(ks keyStorePassphrase, keyAddr common.Address, auth string) (key
keyProtected := new(encryptedKeyJSON)
err = json.Unmarshal(fileContent, keyProtected)
keyId = keyProtected.Id
mac := keyProtected.Crypto.MAC
salt := keyProtected.Crypto.Salt
iv := keyProtected.Crypto.IV
keyId = uuid.Parse(keyProtected.Id)
mac, err := hex.DecodeString(keyProtected.Crypto.MAC)
if err != nil {
return nil, nil, err
}
salt, err := hex.DecodeString(keyProtected.Crypto.Salt)
if err != nil {
return nil, nil, err
}
iv, err := hex.DecodeString(keyProtected.Crypto.IV)
if err != nil {
return nil, nil, err
}
keyHeader := keyProtected.Crypto.KeyHeader
cipherText := keyProtected.Crypto.CipherText
cipherText, err := hex.DecodeString(keyProtected.Crypto.CipherText)
if err != nil {
return nil, nil, err
}
// used in MAC
keyHeaderJSONStr, err := json.Marshal(keyHeader)

View File

@ -98,12 +98,12 @@ func (ks keyStorePlain) DeleteKey(keyAddr common.Address, auth string) (err erro
}
func GetKeyFile(keysDirPath string, keyAddr common.Address) (fileContent []byte, err error) {
fileName := keyAddr.Hex()
fileName := hex.EncodeToString(keyAddr[:])
return ioutil.ReadFile(filepath.Join(keysDirPath, fileName, fileName))
}
func WriteKeyFile(addr common.Address, keysDirPath string, content []byte) (err error) {
addrHex := addr.Hex()
addrHex := hex.EncodeToString(addr[:])
keyDirPath := filepath.Join(keysDirPath, addrHex)
keyFilePath := filepath.Join(keyDirPath, addrHex)
err = os.MkdirAll(keyDirPath, 0700) // read, write and dir search for user