aes.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package service
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/rand"
  7. "encoding/base64"
  8. "errors"
  9. "io"
  10. )
  11. func pad(src []byte) []byte {
  12. padding := aes.BlockSize - len(src)%aes.BlockSize
  13. padText := bytes.Repeat([]byte{byte(padding)}, padding)
  14. return append(src, padText...)
  15. }
  16. func unpad(src []byte) ([]byte, error) {
  17. length := len(src)
  18. unpadding := int(src[length-1])
  19. if unpadding > length {
  20. return nil, errors.New("unpad error. This could happen when incorrect encryption key is used")
  21. }
  22. return src[:(length - unpadding)], nil
  23. }
  24. func (s *Service) encrypt(text string) (string, error) {
  25. msg := pad([]byte(text))
  26. cipherText := make([]byte, aes.BlockSize+len(msg))
  27. iv := cipherText[:aes.BlockSize]
  28. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  29. return "", err
  30. }
  31. cfb := cipher.NewCFBEncrypter(s.AESBlock, iv)
  32. cfb.XORKeyStream(cipherText[aes.BlockSize:], []byte(msg))
  33. finalMsg := base64.URLEncoding.EncodeToString(cipherText)
  34. return finalMsg, nil
  35. }
  36. func (s *Service) decrypt(text string) (string, error) {
  37. decodedMsg, err := base64.URLEncoding.DecodeString(text)
  38. if err != nil {
  39. return "", err
  40. }
  41. if (len(decodedMsg) % aes.BlockSize) != 0 {
  42. return "", errors.New("blocksize must be multipe of decoded message length")
  43. }
  44. iv := decodedMsg[:aes.BlockSize]
  45. msg := decodedMsg[aes.BlockSize:]
  46. cfb := cipher.NewCFBDecrypter(s.AESBlock, iv)
  47. cfb.XORKeyStream(msg, msg)
  48. unpadMsg, err := unpad(msg)
  49. if err != nil {
  50. return "", err
  51. }
  52. return string(unpadMsg), nil
  53. }