aes.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package utils
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "errors"
  7. "io"
  8. )
  9. // GenerateAESKey 生成 AES 密钥
  10. func GenerateAESKey() ([]byte, error) {
  11. key := make([]byte, 32)
  12. _, err := io.ReadFull(rand.Reader, key)
  13. if err != nil {
  14. return nil, err
  15. }
  16. return key, nil
  17. }
  18. // EncryptWithAES 使用 AES 加密数据
  19. func EncryptWithAES(key []byte, plaintext []byte) ([]byte, error) {
  20. block, err := aes.NewCipher(key)
  21. if err != nil {
  22. return nil, err
  23. }
  24. ciphertext := make([]byte, aes.BlockSize+len(plaintext))
  25. iv := ciphertext[:aes.BlockSize]
  26. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  27. return nil, err
  28. }
  29. stream := cipher.NewCFBEncrypter(block, iv)
  30. stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
  31. return ciphertext, nil
  32. }
  33. // DecryptWithAES 使用 AES 解密数据
  34. func DecryptWithAES(key []byte, ciphertext []byte) ([]byte, error) {
  35. block, err := aes.NewCipher(key)
  36. if err != nil {
  37. return nil, err
  38. }
  39. if len(ciphertext) < aes.BlockSize {
  40. return nil, errors.New("ciphertext too short")
  41. }
  42. iv := ciphertext[:aes.BlockSize]
  43. ciphertext = ciphertext[aes.BlockSize:]
  44. stream := cipher.NewCFBDecrypter(block, iv)
  45. stream.XORKeyStream(ciphertext, ciphertext)
  46. // 去填充数据
  47. unpadded, err := unpad(ciphertext)
  48. if err != nil {
  49. return nil, err
  50. }
  51. return unpadded, nil
  52. }
  53. func unpad(buf []byte) ([]byte, error) {
  54. if len(buf) == 0 {
  55. return nil, errors.New("输入缓冲区为空")
  56. }
  57. // 获取最后一个字节作为填充长度
  58. padding := int(buf[len(buf)-1])
  59. // 检查填充是否有效
  60. if padding > len(buf) || padding == 0 {
  61. return nil, errors.New("无效的填充")
  62. }
  63. // 验证填充是否一致
  64. for i := len(buf) - padding; i < len(buf); i++ {
  65. if buf[i] != byte(padding) {
  66. return nil, errors.New("无效的填充")
  67. }
  68. }
  69. // 返回未填充的数据
  70. return buf[:len(buf)-padding], nil
  71. }