Documentation ¶
Overview ¶
package cryptostore maintains everything needed for doing public-key signing and key management in software, based on the go-crypto library from tendermint.
It is flexible, and allows the user to provide a key generation algorithm (currently Ed25519 or Secp256k1), an encoder to passphrase-encrypt our keys when storing them (currently SecretBox from NaCl), and a method to persist the keys (currently FileStorage like ssh, or MemStorage for tests). It should be relatively simple to write your own implementation of these interfaces to match your specific security requirements.
Note that the private keys are never exposed outside the package, and the interface of Manager could be implemented by an HSM in the future for enhanced security. It would require a completely different implementation however.
This Manager aims to implement Signer and KeyManager interfaces, along with some extensions to allow importing/exporting keys and updating the passphrase.
Encoder and Generator implementations are currently in this package, keys.Storage implementations exist as subpackages of keys/storage
Index ¶
- type Encoder
- type GenFunc
- type Generator
- type Manager
- func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error)
- func (s Manager) Delete(name, passphrase string) error
- func (s Manager) Export(name, oldpass, transferpass string) ([]byte, error)
- func (s Manager) Get(name string) (keys.Info, error)
- func (s Manager) Import(name, newpass, transferpass string, data []byte) error
- func (s Manager) List() (keys.Infos, error)
- func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error)
- func (s Manager) Sign(name, passphrase string, tx keys.Signable) error
- func (s Manager) Update(name, oldpass, newpass string) error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Encoder ¶
type Encoder interface { Encrypt(key crypto.PrivKey, pass string) ([]byte, error) Decrypt(data []byte, pass string) (crypto.PrivKey, error) }
Encoder is used to encrypt any key with a passphrase for storage.
This should use a well-designed symetric encryption algorithm
type Generator ¶
Generator determines the type of private key the keystore creates
var ( // GenEd25519 produces Ed25519 private keys GenEd25519 Generator = GenFunc(genEd25519) // GenSecp256k1 produces Secp256k1 private keys GenSecp256k1 Generator = GenFunc(genSecp256) // GenLedgerEd25519 used Ed25519 keys stored on nano ledger s with cosmos app GenLedgerEd25519 Generator = GenFunc(genLedgerEd25519) )
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager combines encyption and storage implementation to provide a full-featured key manager
func New ¶
Example ¶
package main import ( "bytes" "fmt" crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/cryptostore" "github.com/tendermint/go-crypto/keys/storage/memstorage" ) func main() { // Select the encryption and storage for your cryptostore cstore := cryptostore.New( cryptostore.SecretBox, // Note: use filestorage.New(dir) for real data memstorage.New(), keys.MustLoadCodec("english"), ) ed := crypto.NameEd25519 sec := crypto.NameSecp256k1 // Add keys and see they return in alphabetical order bob, _, err := cstore.Create("Bob", "friend", ed) if err != nil { // this should never happen fmt.Println(err) } else { // return info here just like in List fmt.Println(bob.Name) } cstore.Create("Alice", "secret", sec) cstore.Create("Carl", "mitm", ed) info, _ := cstore.List() for _, i := range info { fmt.Println(i.Name) } // We need to use passphrase to generate a signature tx := keys.NewMockSignable([]byte("deadbeef")) err = cstore.Sign("Bob", "friend", tx) if err != nil { fmt.Println("don't accept real passphrase") } // and we can validate the signature with publically available info binfo, _ := cstore.Get("Bob") if !binfo.PubKey.Equals(bob.PubKey) { fmt.Println("Get and Create return different keys") } sigs, err := tx.Signers() if err != nil { fmt.Println("badly signed") } else if bytes.Equal(sigs[0].Bytes(), binfo.PubKey.Bytes()) { fmt.Println("signed by Bob") } else { fmt.Println("signed by someone else") } }
Output: Bob Alice Bob Carl signed by Bob
func (Manager) Create ¶
Create adds a new key to the storage engine, returning error if another key already stored under this name
algo must be a supported go-crypto algorithm: ed25519, secp256k1
func (Manager) Delete ¶
Delete removes key forever, but we must present the proper passphrase before deleting it (for security)
func (Manager) Export ¶
Export decodes the private key with the current password, encodes it with a secure one-time password and generates a sequence that can be Imported by another Manager
This is designed to copy from one device to another, or provide backups during version updates.
func (Manager) Import ¶
Import accepts bytes generated by Export along with the same transferpass If they are valid, it stores the password under the given name with the new passphrase.
func (Manager) Recover ¶ added in v0.2.1
Recover takes a seed phrase and tries to recover the private key.
If the seed phrase is valid, it will create the private key and store it under name, protected by passphrase.
Result similar to New(), except it doesn't return the seed again...