keys: make NEP2Decrypt return a PrivateKey rather than WIF
There is no point in encoding the output of this function in a WIF format, most of the users actually want the real key and those who need a WIF can easily get if from the key (and it's simpler than getting the key from the WIF). It also fixes a severe bug in NEP2Decrypt, base58 decoding errors were not processed correctly.
This commit is contained in:
parent
9a8f5c2a5d
commit
b5b05a969c
4 changed files with 13 additions and 23 deletions
|
@ -14,7 +14,6 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
|
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
|
||||||
"github.com/CityOfZion/neo-go/pkg/wallet"
|
|
||||||
"github.com/nspcc-dev/dbft"
|
"github.com/nspcc-dev/dbft"
|
||||||
"github.com/nspcc-dev/dbft/block"
|
"github.com/nspcc-dev/dbft/block"
|
||||||
"github.com/nspcc-dev/dbft/crypto"
|
"github.com/nspcc-dev/dbft/crypto"
|
||||||
|
@ -178,16 +177,12 @@ func (s *service) validatePayload(p *Payload) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKeyPair(cfg *config.WalletConfig) (crypto.PrivateKey, crypto.PublicKey) {
|
func getKeyPair(cfg *config.WalletConfig) (crypto.PrivateKey, crypto.PublicKey) {
|
||||||
acc, err := wallet.DecryptAccount(cfg.Path, cfg.Password)
|
// TODO: replace with wallet opening from the given path (#588)
|
||||||
|
key, err := keys.NEP2Decrypt(cfg.Path, cfg.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
key := acc.PrivateKey()
|
|
||||||
if key == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,13 +77,13 @@ func NEP2Encrypt(priv *PrivateKey, passphrase string) (s string, err error) {
|
||||||
|
|
||||||
// NEP2Decrypt decrypts an encrypted key using a given passphrase
|
// NEP2Decrypt decrypts an encrypted key using a given passphrase
|
||||||
// under the NEP-2 standard.
|
// under the NEP-2 standard.
|
||||||
func NEP2Decrypt(key, passphrase string) (s string, err error) {
|
func NEP2Decrypt(key, passphrase string) (*PrivateKey, error) {
|
||||||
b, err := base58.CheckDecode(key)
|
b, err := base58.CheckDecode(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s, nil
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := validateNEP2Format(b); err != nil {
|
if err := validateNEP2Format(b); err != nil {
|
||||||
return s, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addrHash := b[3:7]
|
addrHash := b[3:7]
|
||||||
|
@ -91,7 +91,7 @@ func NEP2Decrypt(key, passphrase string) (s string, err error) {
|
||||||
phraseNorm := norm.NFC.Bytes([]byte(passphrase))
|
phraseNorm := norm.NFC.Bytes([]byte(passphrase))
|
||||||
derivedKey, err := scrypt.Key(phraseNorm, addrHash, n, r, p, keyLen)
|
derivedKey, err := scrypt.Key(phraseNorm, addrHash, n, r, p, keyLen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
derivedKey1 := derivedKey[:32]
|
derivedKey1 := derivedKey[:32]
|
||||||
|
@ -100,7 +100,7 @@ func NEP2Decrypt(key, passphrase string) (s string, err error) {
|
||||||
|
|
||||||
decrypted, err := aesDecrypt(encryptedBytes, derivedKey2)
|
decrypted, err := aesDecrypt(encryptedBytes, derivedKey2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
privBytes := xor(decrypted, derivedKey1)
|
privBytes := xor(decrypted, derivedKey1)
|
||||||
|
@ -108,14 +108,14 @@ func NEP2Decrypt(key, passphrase string) (s string, err error) {
|
||||||
// Rebuild the private key.
|
// Rebuild the private key.
|
||||||
privKey, err := NewPrivateKeyFromBytes(privBytes)
|
privKey, err := NewPrivateKeyFromBytes(privBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !compareAddressHash(privKey, addrHash) {
|
if !compareAddressHash(privKey, addrHash) {
|
||||||
return s, errors.New("password mismatch")
|
return nil, errors.New("password mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
return privKey.WIF(), nil
|
return privKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareAddressHash(priv *PrivateKey, inhash []byte) bool {
|
func compareAddressHash(priv *PrivateKey, inhash []byte) bool {
|
||||||
|
|
|
@ -27,18 +27,13 @@ func TestNEP2Encrypt(t *testing.T) {
|
||||||
|
|
||||||
func TestNEP2Decrypt(t *testing.T) {
|
func TestNEP2Decrypt(t *testing.T) {
|
||||||
for _, testCase := range keytestcases.Arr {
|
for _, testCase := range keytestcases.Arr {
|
||||||
|
privKey, err := NEP2Decrypt(testCase.EncryptedWif, testCase.Passphrase)
|
||||||
privKeyString, err := NEP2Decrypt(testCase.EncryptedWif, testCase.Passphrase)
|
|
||||||
if testCase.Invalid {
|
if testCase.Invalid {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
privKey, err := NewPrivateKeyFromWIF(privKeyString)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, testCase.PrivateKey, privKey.String())
|
assert.Equal(t, testCase.PrivateKey, privKey.String())
|
||||||
|
|
||||||
wif := privKey.WIF()
|
wif := privKey.WIF()
|
||||||
|
|
|
@ -63,11 +63,11 @@ func NewAccount() (*Account, error) {
|
||||||
// DecryptAccount decrypts the encryptedWIF with the given passphrase and
|
// DecryptAccount decrypts the encryptedWIF with the given passphrase and
|
||||||
// return the decrypted Account.
|
// return the decrypted Account.
|
||||||
func DecryptAccount(encryptedWIF, passphrase string) (*Account, error) {
|
func DecryptAccount(encryptedWIF, passphrase string) (*Account, error) {
|
||||||
wif, err := keys.NEP2Decrypt(encryptedWIF, passphrase)
|
key, err := keys.NEP2Decrypt(encryptedWIF, passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewAccountFromWIF(wif)
|
return newAccountFromPrivateKey(key), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt encrypts the wallet's PrivateKey with the given passphrase
|
// Encrypt encrypts the wallet's PrivateKey with the given passphrase
|
||||||
|
|
Loading…
Reference in a new issue