aes_util.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package util
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "encoding/hex"
  7. "fmt"
  8. "io"
  9. )
  10. func GenerateKeyAndNonce() (string, string, error) {
  11. // The key argument should be the AES key, either 16 or 32 bytes
  12. // to select AES-128 or AES-256.
  13. key := make([]byte, 32)
  14. if _, err := io.ReadFull(rand.Reader, key); err != nil {
  15. return "", "", err
  16. }
  17. // Never use more than 2^32 random nonces with a given key because of
  18. // the risk of a repeat.
  19. nonce := make([]byte, 12)
  20. if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
  21. return "", "", err
  22. }
  23. return fmt.Sprintf("%x", key), fmt.Sprintf("%x", nonce), nil
  24. }
  25. func ValidateKeyAndNonce(keyHexStr, nonceHexStr string) ([]byte, []byte, error) {
  26. key, err := hex.DecodeString(keyHexStr)
  27. if err != nil {
  28. return nil, nil, err
  29. }
  30. nonce, err := hex.DecodeString(nonceHexStr)
  31. if err != nil {
  32. return nil, nil, err
  33. }
  34. return key, nonce, nil
  35. }
  36. func Encrypt(key []byte, nonce []byte, plainText string) (string, error) {
  37. block, err := aes.NewCipher(key)
  38. if err != nil {
  39. return "", err
  40. }
  41. aesgcm, err := cipher.NewGCM(block)
  42. if err != nil {
  43. return "", err
  44. }
  45. cipherText := aesgcm.Seal(nil, nonce, []byte(plainText), nil)
  46. return fmt.Sprintf("%x", cipherText), nil
  47. }
  48. func Decrypt(key []byte, nonce []byte, cipherHexStr string) (string, error) {
  49. block, err := aes.NewCipher(key)
  50. if err != nil {
  51. return "", err
  52. }
  53. aesgcm, err := cipher.NewGCM(block)
  54. if err != nil {
  55. return "", err
  56. }
  57. cipherText, err := hex.DecodeString(cipherHexStr)
  58. if err != nil {
  59. return "", err
  60. }
  61. plainText, err := aesgcm.Open(nil, nonce, []byte(cipherText), nil)
  62. if err != nil {
  63. return "", err
  64. }
  65. return string(plainText), nil
  66. }