cipher-func.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package locals
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/rand"
  7. "encoding/base64"
  8. "errors"
  9. "io"
  10. "strings"
  11. e "github.com/dabory/abango-rest/etc"
  12. )
  13. //if keysize is 16bytes * 8bits -> 128
  14. //if keysize is 32bytes * 8bits -> 256
  15. //Encrypt-Decript는 plaintext가 16bytes 밖에는 지원하지 않는다 따라서
  16. //MyAesEncrypt를 사용한다.
  17. func MyAesEncrypt(key []byte, text []byte) ([]byte, error) {
  18. block, err := aes.NewCipher(key)
  19. if err != nil {
  20. return nil, errors.New(e.FuncRunErr("odvjkwei3", e.CurrFuncName()+" "+err.Error()))
  21. }
  22. msg := Pad(text)
  23. ciphertext := make([]byte, aes.BlockSize+len(msg))
  24. iv := ciphertext[:aes.BlockSize]
  25. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  26. return nil, errors.New(e.FuncRunErr("ls0ue3so", e.CurrFuncName()+" "+err.Error()))
  27. }
  28. cfb := cipher.NewCFBEncrypter(block, iv)
  29. cfb.XORKeyStream(ciphertext[aes.BlockSize:], msg)
  30. finalMsg := removeBase64Padding(base64.URLEncoding.EncodeToString(ciphertext))
  31. return []byte(finalMsg), nil
  32. }
  33. func MyAesDecrypt(key []byte, text []byte) ([]byte, error) {
  34. block, err := aes.NewCipher(key)
  35. if err != nil {
  36. return nil, errors.New(e.FuncRunErr("3do8awe", e.CurrFuncName()+" "+err.Error()))
  37. }
  38. decodedMsg, err := base64.URLEncoding.DecodeString(addBase64Padding(string(text)))
  39. if err != nil {
  40. return nil, errors.New(e.FuncRunErr("mkshewjd", e.CurrFuncName()+" "+err.Error()))
  41. }
  42. if (len(decodedMsg) % aes.BlockSize) != 0 {
  43. return nil, errors.New(e.FuncRunErr("mskoeuwid", e.CurrFuncName()+" "+err.Error()))
  44. }
  45. iv := decodedMsg[:aes.BlockSize]
  46. msg := decodedMsg[aes.BlockSize:]
  47. cfb := cipher.NewCFBDecrypter(block, iv)
  48. cfb.XORKeyStream(msg, msg)
  49. unpadMsg, err := Unpad(msg)
  50. if err != nil {
  51. return nil, errors.New(e.FuncRunErr("012bsoo832d", e.CurrFuncName()+" "+err.Error()))
  52. }
  53. return unpadMsg, nil
  54. }
  55. func Pad(src []byte) []byte {
  56. padding := aes.BlockSize - len(src)%aes.BlockSize
  57. padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  58. return append(src, padtext...)
  59. }
  60. func Unpad(src []byte) ([]byte, error) {
  61. length := len(src)
  62. unpadding := int(src[length-1])
  63. if unpadding > length {
  64. return nil, errors.New(e.FuncRunErr("unpad error. This could happen when incorrect MyAesEncryption key is used", e.CurrFuncName()))
  65. }
  66. return src[:(length - unpadding)], nil
  67. }
  68. func addBase64Padding(value string) string {
  69. m := len(value) % 4
  70. if m != 0 {
  71. value += strings.Repeat("=", 4-m)
  72. }
  73. return value
  74. }
  75. func removeBase64Padding(value string) string {
  76. return strings.Replace(value, "=", "", -1)
  77. }