encdec.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package utils
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "encoding/base64"
  7. "fmt"
  8. "io"
  9. "strings"
  10. )
  11. // 加密密钥(32字节,用于AES-256)
  12. var key = []byte("change-me-MUST-32-BIT-1234567890")
  13. // 自定义Base64编码表,这里排除了'+'和'/'
  14. const customBase64Table = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
  15. func CustomBase64Encode(src []byte) string {
  16. // 创建一个使用自定义编码表的Base64编码器
  17. encoder := base64.NewEncoding(customBase64Table)
  18. return encoder.EncodeToString(src)
  19. }
  20. func CustomBase64Decode(encoded string) ([]byte, error) {
  21. // 创建一个使用自定义编码表的Base64解码器
  22. decoder := base64.NewEncoding(customBase64Table)
  23. return decoder.DecodeString(encoded)
  24. }
  25. // SetKey updates the current encryption key to the provided byte slice.
  26. // The newKey should be 32 bytes long for AES-256 encryption.
  27. // It modifies the global 'key' variable which is used as the encryption key.
  28. func SetKey(newKey string) error {
  29. if len(newKey) != 32 {
  30. return fmt.Errorf("key must be 32 bytes long")
  31. }
  32. key = []byte(newKey)
  33. return nil
  34. }
  35. func SetKeyInBytes(newKey []byte) error {
  36. if len(newKey) != 32 {
  37. return fmt.Errorf("key must be 32 bytes long")
  38. }
  39. key = newKey
  40. return nil
  41. }
  42. // Encrypt2 encrypts plaintext using AES encryption.
  43. func Encrypt2(plaintext string) (string, error) {
  44. block, err := aes.NewCipher(key)
  45. if err != nil {
  46. return "", err
  47. }
  48. ciphertext := make([]byte, aes.BlockSize+len(plaintext))
  49. iv := ciphertext[:aes.BlockSize]
  50. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  51. return "", err
  52. }
  53. stream := cipher.NewCFBEncrypter(block, iv)
  54. stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(plaintext))
  55. return CustomBase64Encode(ciphertext), nil
  56. }
  57. // Decrypt2 decrypts ciphertext back to plaintext.
  58. func Decrypt2(ciphertext string) (string, error) {
  59. ciphertextBytes, err := CustomBase64Decode(ciphertext)
  60. if err != nil {
  61. return "", err
  62. }
  63. block, err := aes.NewCipher(key)
  64. if err != nil {
  65. return "", err
  66. }
  67. if len(ciphertextBytes) < aes.BlockSize {
  68. return "", fmt.Errorf("ciphertext too short")
  69. }
  70. iv := ciphertextBytes[:aes.BlockSize]
  71. ciphertextBytes = ciphertextBytes[aes.BlockSize:]
  72. stream := cipher.NewCFBDecrypter(block, iv)
  73. stream.XORKeyStream(ciphertextBytes, ciphertextBytes)
  74. return string(ciphertextBytes), nil
  75. }
  76. // Encode function combines the elements of strings slice into a single string and returns it.
  77. func Encode(data []string) (string, error) {
  78. for _, element := range data {
  79. if strings.Contains(element, "||") {
  80. return "", fmt.Errorf("elements cannot contain '||' character")
  81. }
  82. }
  83. combined := strings.Join(data, "||")
  84. return Encrypt2(combined)
  85. }
  86. func Decode(encoded string) ([]string, error) {
  87. decrypted, err := Decrypt2(encoded)
  88. if err != nil {
  89. return nil, err
  90. }
  91. parts := strings.Split(decrypted, "||")
  92. return parts, nil
  93. }