encrypt.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package repository
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "errors"
  7. "io"
  8. )
  9. // This file is copied from: https://github.com/gtank/cryptopasta
  10. // NewEncryptionKey generates a random 256-bit key for Encrypt() and
  11. // Decrypt(). It panics if the source of randomness fails.
  12. func NewEncryptionKey() *[32]byte {
  13. key := [32]byte{}
  14. _, err := io.ReadFull(rand.Reader, key[:])
  15. if err != nil {
  16. panic(err)
  17. }
  18. return &key
  19. }
  20. // Encrypt encrypts data using 256-bit AES-GCM. This both hides the content of
  21. // the data and provides a check that it hasn't been altered. Output takes the
  22. // form nonce|ciphertext|tag where '|' indicates concatenation.
  23. func Encrypt(plaintext []byte, key *[32]byte) (ciphertext []byte, err error) {
  24. block, err := aes.NewCipher(key[:])
  25. if err != nil {
  26. return nil, err
  27. }
  28. gcm, err := cipher.NewGCM(block)
  29. if err != nil {
  30. return nil, err
  31. }
  32. nonce := make([]byte, gcm.NonceSize())
  33. _, err = io.ReadFull(rand.Reader, nonce)
  34. if err != nil {
  35. return nil, err
  36. }
  37. return gcm.Seal(nonce, nonce, plaintext, nil), nil
  38. }
  39. // Decrypt decrypts data using 256-bit AES-GCM. This both hides the content of
  40. // the data and provides a check that it hasn't been altered. Expects input
  41. // form nonce|ciphertext|tag where '|' indicates concatenation.
  42. func Decrypt(ciphertext []byte, key *[32]byte) (plaintext []byte, err error) {
  43. block, err := aes.NewCipher(key[:])
  44. if err != nil {
  45. return nil, err
  46. }
  47. gcm, err := cipher.NewGCM(block)
  48. if err != nil {
  49. return nil, err
  50. }
  51. if len(ciphertext) < gcm.NonceSize() {
  52. return nil, errors.New("malformed ciphertext")
  53. }
  54. return gcm.Open(nil,
  55. ciphertext[:gcm.NonceSize()],
  56. ciphertext[gcm.NonceSize():],
  57. nil,
  58. )
  59. }