encrypt.go 1.9 KB

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