encrypt.go 2.9 KB

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