cipher.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package util
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/rand"
  7. "errors"
  8. "fmt"
  9. "io"
  10. "io/ioutil"
  11. "github.com/chrislusf/seaweedfs/weed/glog"
  12. )
  13. type CipherKey []byte
  14. func GenCipherKey() CipherKey {
  15. key := make([]byte, 32)
  16. if _, err := io.ReadFull(rand.Reader, key); err != nil {
  17. glog.Fatalf("random key gen: %v", err)
  18. }
  19. return CipherKey(key)
  20. }
  21. func Encrypt(plaintext []byte, key CipherKey) ([]byte, error) {
  22. c, err := aes.NewCipher(key)
  23. if err != nil {
  24. return nil, err
  25. }
  26. gcm, err := cipher.NewGCM(c)
  27. if err != nil {
  28. return nil, err
  29. }
  30. nonce := make([]byte, gcm.NonceSize())
  31. if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
  32. return nil, err
  33. }
  34. return gcm.Seal(nonce, nonce, plaintext, nil), nil
  35. }
  36. func Decrypt(ciphertext []byte, key CipherKey) ([]byte, error) {
  37. c, err := aes.NewCipher(key)
  38. if err != nil {
  39. return nil, err
  40. }
  41. gcm, err := cipher.NewGCM(c)
  42. if err != nil {
  43. return nil, err
  44. }
  45. nonceSize := gcm.NonceSize()
  46. if len(ciphertext) < nonceSize {
  47. return nil, errors.New("ciphertext too short")
  48. }
  49. nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
  50. return gcm.Open(nil, nonce, ciphertext, nil)
  51. }
  52. func EncryptReader(clearReader io.Reader) (cipherKey CipherKey, encryptedReader io.ReadCloser, clearDataLen, encryptedDataLen int, err error) {
  53. clearData, err := ioutil.ReadAll(clearReader)
  54. if err != nil {
  55. err = fmt.Errorf("read raw input: %v", err)
  56. return
  57. }
  58. clearDataLen = len(clearData)
  59. cipherKey = GenCipherKey()
  60. encryptedData, err := Encrypt(clearData, cipherKey)
  61. if err != nil {
  62. err = fmt.Errorf("encrypt input: %v", err)
  63. return
  64. }
  65. encryptedDataLen = len(encryptedData)
  66. encryptedReader = ioutil.NopCloser(bytes.NewReader(encryptedData))
  67. return
  68. }