github.com/elastos/Elastos.ELA.SideChain.ETH@v0.2.2/chainbridge-core/keystore/decrypt.go (about) 1 // Copyright 2020 ChainSafe Systems 2 // SPDX-License-Identifier: LGPL-3.0-only 3 4 package keystore 5 6 import ( 7 "errors" 8 "fmt" 9 "io/ioutil" 10 "path/filepath" 11 12 "github.com/elastos/Elastos.ELA.SideChain.ESC/accounts/keystore" 13 "github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/crypto" 14 "github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/crypto/secp256k1" 15 ) 16 17 // Decrypt uses AES to decrypt ciphertext with the symmetric key deterministically created from `password` 18 func Decrypt(data, password []byte) ([]byte, error) { 19 gcm, err := gcmFromPassphrase(password) 20 if err != nil { 21 return nil, err 22 } 23 24 nonceSize := gcm.NonceSize() 25 nonce, ciphertext := data[:nonceSize], data[nonceSize:] 26 plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) 27 if err != nil { 28 if err.Error() == "cipher: message authentication failed" { 29 err = errors.New(err.Error() + ". Incorrect Password.") 30 } 31 return nil, err 32 } 33 34 return plaintext, nil 35 } 36 37 // DecodeKeypair turns input bytes into a keypair based on the specified key type 38 func DecodeKeypair(in []byte, keytype crypto.KeyType) (kp crypto.Keypair, err error) { 39 if keytype == crypto.Secp256k1Type { 40 kp = &secp256k1.Keypair{} 41 err = kp.Decode(in) 42 } else { 43 return nil, errors.New("cannot decode key: invalid key type") 44 } 45 46 return kp, err 47 } 48 49 // DecryptPrivateKey uses AES to decrypt the ciphertext into a `crypto.PrivateKey` with a symmetric key deterministically 50 // created from `password` 51 func DecryptKeypair(expectedPubK string, data, password []byte, keytype string) (crypto.Keypair, error) { 52 pk, err := Decrypt(data, password) 53 if err != nil { 54 return nil, err 55 } 56 kp, err := DecodeKeypair(pk, keytype) 57 if err != nil { 58 return nil, err 59 } 60 61 // Check that the decoding matches what was expected 62 if kp.PublicKey() != expectedPubK { 63 return nil, fmt.Errorf("unexpected key file data, file may be corrupt or have been tampered with") 64 } 65 return kp, nil 66 } 67 68 // ReadFromFileAndDecrypt reads ciphertext from a file and decrypts it using the password into a `crypto.PrivateKey` 69 func ReadFromFileAndDecrypt(filename string, password []byte, keytype string) (crypto.Keypair, error) { 70 fp, err := filepath.Abs(filename) 71 if err != nil { 72 return nil, err 73 } 74 75 data, err := ioutil.ReadFile(filepath.Clean(fp)) 76 if err != nil { 77 return nil, err 78 } 79 key, err := keystore.DecryptKey(data, string(password)) 80 if err != nil { 81 return nil, err 82 } 83 _ = key 84 return secp256k1.NewKeypair(*key.PrivateKey), nil 85 }