You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
1.5 KiB

  1. package cryptostore
  2. import (
  3. "github.com/pkg/errors"
  4. crypto "github.com/tendermint/go-crypto"
  5. )
  6. var (
  7. // SecretBox uses the algorithm from NaCL to store secrets securely
  8. SecretBox Encoder = secretbox{}
  9. // Noop doesn't do any encryption, should only be used in test code
  10. Noop Encoder = noop{}
  11. )
  12. // Encoder is used to encrypt any key with a passphrase for storage.
  13. //
  14. // This should use a well-designed symetric encryption algorithm
  15. type Encoder interface {
  16. Encrypt(key crypto.PrivKey, pass string) ([]byte, error)
  17. Decrypt(data []byte, pass string) (crypto.PrivKey, error)
  18. }
  19. func secret(passphrase string) []byte {
  20. // TODO: Sha256(Bcrypt(passphrase))
  21. return crypto.Sha256([]byte(passphrase))
  22. }
  23. type secretbox struct{}
  24. func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) {
  25. if pass == "" {
  26. return key.Bytes(), nil
  27. }
  28. s := secret(pass)
  29. cipher := crypto.EncryptSymmetric(key.Bytes(), s)
  30. return cipher, nil
  31. }
  32. func (e secretbox) Decrypt(data []byte, pass string) (key crypto.PrivKey, err error) {
  33. private := data
  34. if pass != "" {
  35. s := secret(pass)
  36. private, err = crypto.DecryptSymmetric(data, s)
  37. if err != nil {
  38. return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase")
  39. }
  40. }
  41. key, err = crypto.PrivKeyFromBytes(private)
  42. return key, errors.Wrap(err, "Invalid Passphrase")
  43. }
  44. type noop struct{}
  45. func (n noop) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) {
  46. return key.Bytes(), nil
  47. }
  48. func (n noop) Decrypt(data []byte, pass string) (crypto.PrivKey, error) {
  49. return crypto.PrivKeyFromBytes(data)
  50. }