encrypt.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // 加密算法库
  2. package util
  3. import (
  4. "crypto/cipher"
  5. "crypto/md5"
  6. )
  7. const (
  8. XOR_KEY_LEN = 32
  9. XOR_IV_LEN = 32
  10. )
  11. // 定义一些加密方法
  12. var CipherMethod = map[string]*CipherInfo{
  13. "plain": {0, 0, NewPlainStream, NewPlainStream},
  14. "xor": {XOR_KEY_LEN, XOR_IV_LEN, NewXorStream, NewXorStream},
  15. }
  16. // 普通的xor加密,没有破解的难度,只是简单的让明文不可见而已
  17. type XorStreamCipher struct {
  18. key [XOR_KEY_LEN]byte
  19. index byte // 加解密的位置指示
  20. }
  21. func (c *XorStreamCipher) XORKeyStream(dst, src []byte) {
  22. l := len(src)
  23. for i := range l {
  24. dst[i] = src[i] ^ c.key[c.index]
  25. c.index++
  26. if c.index >= XOR_KEY_LEN {
  27. c.index = 0
  28. }
  29. }
  30. }
  31. func NewXorStream(key, iv []byte) (cipher.Stream, error) {
  32. var c XorStreamCipher
  33. copy(c.key[:], key[:XOR_KEY_LEN])
  34. for i := range XOR_KEY_LEN {
  35. c.key[i] = c.key[i] ^ iv[i]
  36. }
  37. return &c, nil
  38. }
  39. // 没有加密模式,考虑到部分通讯管道已经是加密的状态,故增加不加密的方式,提高速度
  40. type PlainStreamCipher struct{}
  41. func (c *PlainStreamCipher) XORKeyStream(dst, src []byte) {
  42. if &dst != &src {
  43. copy(dst, src)
  44. }
  45. }
  46. func NewPlainStream(key, iv []byte) (cipher.Stream, error) {
  47. var c PlainStreamCipher
  48. return &c, nil
  49. }
  50. func Md5Sum(d []byte) []byte {
  51. h := md5.New()
  52. h.Write(d)
  53. return h.Sum(nil)
  54. }
  55. // 转字符串密码为byte数组类型
  56. func EvpBytesToKey(password string, keyLen int) (key []byte) {
  57. if keyLen <= 1 {
  58. return
  59. }
  60. const md5Len = 16
  61. cnt := (keyLen-1)/md5Len + 1
  62. m := make([]byte, cnt*md5Len)
  63. copy(m, Md5Sum([]byte(password)))
  64. // Repeatedly call md5 until bytes generated is enough.
  65. // Each call to md5 uses data: prev md5 sum + password.
  66. d := make([]byte, md5Len+len(password))
  67. start := 0
  68. for i := 1; i < cnt; i++ {
  69. start += md5Len
  70. copy(d, m[start-md5Len:start])
  71. copy(d[md5Len:], password)
  72. copy(m[start:], Md5Sum(d))
  73. }
  74. return m[:keyLen]
  75. }
  76. // 预先准备好的加密算法
  77. type CipherInfo struct {
  78. KeyLen int
  79. IvLen int
  80. NewEncryptStream func(key, iv []byte) (cipher.Stream, error)
  81. NewDecryptStream func(key, iv []byte) (cipher.Stream, error)
  82. }
  83. // 建立一个cipher对加密算法统一管理
  84. type Cipher struct {
  85. enc cipher.Stream
  86. dec cipher.Stream
  87. }
  88. func (c *Cipher) Encrypt(dst, src []byte) {
  89. c.enc.XORKeyStream(dst, src)
  90. }
  91. func (c *Cipher) Decrypt(dst, src []byte) {
  92. c.dec.XORKeyStream(dst, src)
  93. }
  94. // 新建 cipher
  95. func NewCipher(ci *CipherInfo, pwd string, eiv []byte, div []byte) (c *Cipher, err error) {
  96. key := EvpBytesToKey(pwd, ci.KeyLen)
  97. enc, err := ci.NewEncryptStream(key, eiv)
  98. if err != nil {
  99. return nil, err
  100. }
  101. dec, err := ci.NewDecryptStream(key, div)
  102. if err != nil {
  103. return nil, err
  104. }
  105. c = &Cipher{
  106. enc: enc,
  107. dec: dec,
  108. }
  109. return
  110. }