pcrypto.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package pcrypto
  2. import (
  3. "bytes"
  4. "compress/gzip"
  5. "crypto/aes"
  6. "crypto/cipher"
  7. "encoding/base64"
  8. "encoding/hex"
  9. "errors"
  10. "fmt"
  11. "io/ioutil"
  12. )
  13. type Pcrypto struct {
  14. pkey []byte
  15. paes cipher.Block
  16. }
  17. func (pc *Pcrypto) Init(key []byte) error {
  18. var err error
  19. pc.pkey = PKCS7Padding(key, aes.BlockSize)
  20. pc.paes, err = aes.NewCipher(pc.pkey)
  21. return err
  22. }
  23. func (pc *Pcrypto) Encrypto(src []byte) ([]byte, error) {
  24. // aes
  25. src = PKCS7Padding(src, aes.BlockSize)
  26. blockMode := cipher.NewCBCEncrypter(pc.paes, pc.pkey)
  27. crypted := make([]byte, len(src))
  28. blockMode.CryptBlocks(crypted, src)
  29. // gzip
  30. var zbuf bytes.Buffer
  31. zwr := gzip.NewWriter(&zbuf)
  32. defer zwr.Close()
  33. zwr.Write(crypted)
  34. zwr.Flush()
  35. // base64
  36. return []byte(base64.StdEncoding.EncodeToString(zbuf.Bytes())), nil
  37. }
  38. func (pc *Pcrypto) Decrypto(str []byte) ([]byte, error) {
  39. // base64
  40. data, err := base64.StdEncoding.DecodeString(string(str))
  41. if err != nil {
  42. return nil, err
  43. }
  44. // gunzip
  45. zbuf := bytes.NewBuffer(data)
  46. zrd, _ := gzip.NewReader(zbuf)
  47. defer zrd.Close()
  48. data, _ = ioutil.ReadAll(zrd)
  49. // aes
  50. decryptText, err := hex.DecodeString(fmt.Sprintf("%x", data))
  51. if err != nil {
  52. return nil, err
  53. }
  54. if len(decryptText)%aes.BlockSize != 0 {
  55. return nil, errors.New("crypto/cipher: ciphertext is not a multiple of the block size")
  56. }
  57. blockMode := cipher.NewCBCDecrypter(pc.paes, pc.pkey)
  58. blockMode.CryptBlocks(decryptText, decryptText)
  59. decryptText = PKCS7UnPadding(decryptText)
  60. return decryptText, nil
  61. }
  62. func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
  63. padding := blockSize - len(ciphertext)%blockSize
  64. padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  65. return append(ciphertext, padtext...)
  66. }
  67. func PKCS7UnPadding(origData []byte) []byte {
  68. length := len(origData)
  69. unpadding := int(origData[length-1])
  70. return origData[:(length - unpadding)]
  71. }