key_gen.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. type KeyGenerator struct {
  16. AESKey string
  17. }
  18. func encryptAESCFB(msg, key []byte) ([]byte, error) {
  19. block, err := aes.NewCipher(key)
  20. if err != nil {
  21. return nil, err
  22. }
  23. ciphertext := make([]byte, aes.BlockSize+len(msg))
  24. iv := ciphertext[:aes.BlockSize]
  25. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  26. return nil, err
  27. }
  28. stream := cipher.NewCFBEncrypter(block, iv)
  29. stream.XORKeyStream(ciphertext[aes.BlockSize:], msg)
  30. return ciphertext, nil
  31. }
  32. func decryptAESCFB(msg, key []byte) ([]byte, error) {
  33. block, err := aes.NewCipher(key)
  34. if err != nil {
  35. return nil, err
  36. }
  37. if len(msg) < aes.BlockSize {
  38. return nil, errors.New("decrypt message too short")
  39. }
  40. iv := msg[:aes.BlockSize]
  41. msg = msg[aes.BlockSize:]
  42. stream := cipher.NewCFBDecrypter(block, iv)
  43. stream.XORKeyStream(msg, msg)
  44. return msg, nil
  45. }
  46. func NewKeyGenerator(key string) (*KeyGenerator, error) {
  47. l := len(key)
  48. if l != 16 && l != 24 && l != 32 {
  49. return nil, errors.New("invalid aes key length, should be 16, 24 or 32 bytes.")
  50. }
  51. return &KeyGenerator{
  52. AESKey: key,
  53. }, nil
  54. }
  55. func (g *KeyGenerator) GenRandomKey(id uint) (string, error) {
  56. buf := make([]byte, maxEncodeLen-binary.Size(id)-aes.BlockSize)
  57. if _, err := io.ReadFull(rand.Reader, buf); err != nil {
  58. return "", nil
  59. }
  60. binid := bytes.NewBuffer([]byte{})
  61. binary.Write(binid, binary.BigEndian, id)
  62. buf = append(buf, binid.Bytes()...)
  63. binkey, err := encryptAESCFB(buf, []byte(g.AESKey))
  64. if err != nil {
  65. return "", err
  66. }
  67. return hex.EncodeToString(binkey), nil
  68. }
  69. // get id from encrypt strings
  70. func (g *KeyGenerator) DecodeIdFromRandomKey(encrypted string) (int64, error) {
  71. buf, err := hex.DecodeString(encrypted)
  72. if err != nil {
  73. return 0, err
  74. }
  75. raw, err := decryptAESCFB(buf, []byte(g.AESKey))
  76. if err != nil {
  77. return 0, err
  78. }
  79. var id int64
  80. if len(raw) > maxEncodeLen || len(raw) < maxEncodeLen-aes.BlockSize-binary.Size(id) {
  81. return 0, errors.New("invalid key format.")
  82. }
  83. binbuf := bytes.NewBuffer(raw[maxEncodeLen-aes.BlockSize-binary.Size(id):])
  84. binary.Read(binbuf, binary.BigEndian, &id)
  85. return id, nil
  86. }