key_gen.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package generator
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/rand"
  7. "encoding/binary"
  8. "encoding/hex"
  9. "errors"
  10. "io"
  11. )
  12. const (
  13. maxEncodeLen = 32
  14. )
  15. // KeyGenerator key generator
  16. type KeyGenerator struct {
  17. AESKey string
  18. }
  19. func encryptAESCFB(msg, key []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(msg))
  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:], msg)
  31. return ciphertext, nil
  32. }
  33. func decryptAESCFB(msg, key []byte) ([]byte, error) {
  34. block, err := aes.NewCipher(key)
  35. if err != nil {
  36. return nil, err
  37. }
  38. if len(msg) < aes.BlockSize {
  39. return nil, errors.New("decrypt message too short")
  40. }
  41. iv := msg[:aes.BlockSize]
  42. msg = msg[aes.BlockSize:]
  43. stream := cipher.NewCFBDecrypter(block, iv)
  44. stream.XORKeyStream(msg, msg)
  45. return msg, nil
  46. }
  47. // NewKeyGenerator create a key generator
  48. func NewKeyGenerator(key string) (*KeyGenerator, error) {
  49. l := len(key)
  50. if l != 16 && l != 24 && l != 32 {
  51. return nil, errors.New("invalid aes key length, should be 16, 24 or 32 bytes")
  52. }
  53. return &KeyGenerator{
  54. AESKey: key,
  55. }, nil
  56. }
  57. // GenRandomKey get random key
  58. func (g *KeyGenerator) GenRandomKey(id int64) (string, error) {
  59. buf := make([]byte, maxEncodeLen-binary.Size(id)-aes.BlockSize)
  60. if _, err := io.ReadFull(rand.Reader, buf); err != nil {
  61. return "", nil
  62. }
  63. binid := bytes.NewBuffer([]byte{})
  64. binary.Write(binid, binary.BigEndian, id)
  65. buf = append(buf, binid.Bytes()...)
  66. binkey, err := encryptAESCFB(buf, []byte(g.AESKey))
  67. if err != nil {
  68. return "", err
  69. }
  70. return hex.EncodeToString(binkey), nil
  71. }
  72. // DecodeIDFromRandomKey get id from encrypt strings
  73. func (g *KeyGenerator) DecodeIDFromRandomKey(encrypted string) (int64, error) {
  74. buf, err := hex.DecodeString(encrypted)
  75. if err != nil {
  76. return 0, err
  77. }
  78. raw, err := decryptAESCFB(buf, []byte(g.AESKey))
  79. if err != nil {
  80. return 0, err
  81. }
  82. var id int64
  83. if len(raw) > maxEncodeLen || len(raw) < maxEncodeLen-aes.BlockSize-binary.Size(id) {
  84. return 0, errors.New("invalid key format")
  85. }
  86. binbuf := bytes.NewBuffer(raw[maxEncodeLen-aes.BlockSize-binary.Size(id):])
  87. binary.Read(binbuf, binary.BigEndian, &id)
  88. return id, nil
  89. }