广告平台(站长使用)
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

prpcrypt.go 1.4 KiB

3 달 전
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package wechat
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "encoding/base64"
  7. "io"
  8. )
  9. type prpCrypt struct {
  10. Key []byte
  11. Iv []byte
  12. }
  13. func NewPrpCrypt(aesKey string) *prpCrypt {
  14. instance := new(prpCrypt)
  15. //网络字节序
  16. instance.Key, _ = base64.StdEncoding.DecodeString(aesKey + "=")
  17. instance.Iv = randomIv()
  18. return instance
  19. }
  20. func randomIv() []byte {
  21. iv := make([]byte, aes.BlockSize)
  22. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  23. panic("random iv error")
  24. }
  25. return iv
  26. }
  27. func (prp *prpCrypt) decrypt(encrypted string) ([]byte, error) {
  28. encryptedBytes, _ := base64.StdEncoding.DecodeString(encrypted)
  29. k := len(prp.Key) //PKCS#7
  30. if len(encryptedBytes)%k != 0 {
  31. panic("ciphertext size is not multiple of aes key length")
  32. }
  33. block, err := aes.NewCipher(prp.Key)
  34. if err != nil {
  35. return nil, err
  36. }
  37. blockMode := cipher.NewCBCDecrypter(block, prp.Iv)
  38. plainText := make([]byte, len(encryptedBytes))
  39. blockMode.CryptBlocks(plainText, encryptedBytes)
  40. return plainText, nil
  41. }
  42. func (prp *prpCrypt) encrypt(plainText []byte) ([]byte, error) {
  43. k := len(prp.Key)
  44. if len(plainText)%k != 0 {
  45. plainText = pKCS7Pad(plainText, k)
  46. }
  47. block, err := aes.NewCipher(prp.Key)
  48. if err != nil {
  49. return nil, err
  50. }
  51. cipherData := make([]byte, len(plainText))
  52. blockMode := cipher.NewCBCEncrypter(block, prp.Iv)
  53. blockMode.CryptBlocks(cipherData, plainText)
  54. return cipherData, nil
  55. }