加密
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
5.0 KiB

3 years ago
  1. // DES、3DES加解密示例,
  2. package crypter
  3. import (
  4. "bytes"
  5. "crypto/cipher"
  6. "crypto/des"
  7. "encoding/base64"
  8. "encoding/hex"
  9. "errors"
  10. "log"
  11. "strings"
  12. )
  13. const KEYS = "gfe023u_sefiel#fi32lf3z!" //必须24位
  14. /**
  15. * 加密并转换为base64字符串
  16. */
  17. func DesEncrypt(args ...string) (string, error) { //origData, key []byte
  18. code, keyorg, err := getArgs(args)
  19. if err != nil {
  20. return "", err
  21. }
  22. key := keyorg[0:8]
  23. block, err := des.NewCipher(key)
  24. if err != nil {
  25. return "", err
  26. }
  27. origData := []byte(code)
  28. origData = PKCS5Padding(origData, block.BlockSize())
  29. blockMode := cipher.NewCBCEncrypter(block, key)
  30. crypted := make([]byte, len(origData))
  31. // 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
  32. // crypted := origData
  33. blockMode.CryptBlocks(crypted, origData)
  34. encode := base64.StdEncoding.EncodeToString(crypted)
  35. return encode, nil
  36. }
  37. /**
  38. * 加密并转换为16进制字符串
  39. */
  40. func DesEn(code, key string) string {
  41. block, err := des.NewCipher([]byte(key))
  42. if err != nil {
  43. return ""
  44. }
  45. origData := []byte(code)
  46. origData = PKCS5Padding(origData, block.BlockSize())
  47. blockMode := cipher.NewCBCEncrypter(block, []byte(key))
  48. crypted := make([]byte, len(origData))
  49. // 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
  50. // crypted := origData
  51. blockMode.CryptBlocks(crypted, origData)
  52. return strings.ToUpper(hex.EncodeToString(crypted))
  53. }
  54. /**
  55. * 解密已转为base64字符串有DES加密
  56. */
  57. func DesDecrypt(args ...string) (string, error) {
  58. decode, keyorg, err := getArgs(args)
  59. if err != nil {
  60. return "", err
  61. }
  62. key := keyorg[0:8]
  63. crypted, err := base64.StdEncoding.DecodeString(decode)
  64. block, err := des.NewCipher([]byte(key))
  65. if err != nil {
  66. return "", err
  67. }
  68. blockMode := cipher.NewCBCDecrypter(block, key)
  69. if len(crypted)%blockMode.BlockSize() != 0 {
  70. return "", errors.New("error,input not full blocks")
  71. }
  72. origData := make([]byte, len(crypted))
  73. blockMode.CryptBlocks(origData, crypted)
  74. origData = PKCS5UnPadding(origData)
  75. return string(origData), nil
  76. }
  77. /**
  78. * 解密已转为16进制字符串有DES加密
  79. */
  80. func DesDe(code, key string) string {
  81. crypted, err := hex.DecodeString(code)
  82. if err != nil {
  83. return ""
  84. }
  85. block, err := des.NewCipher([]byte(key))
  86. if err != nil {
  87. return ""
  88. }
  89. blockMode := cipher.NewCBCDecrypter(block, []byte(key))
  90. if len(crypted)%blockMode.BlockSize() != 0 {
  91. return ""
  92. }
  93. origData := make([]byte, len(crypted))
  94. blockMode.CryptBlocks(origData, crypted)
  95. origData = PKCS5UnPadding(origData)
  96. return string(origData)
  97. }
  98. // 3DES加密, 可与php MCRYPT_3DES加密方式对应
  99. func TripleDesEncrypt(args ...string) (string, error) {
  100. code, key, err := getArgs(args)
  101. if err != nil {
  102. return "", err
  103. }
  104. if code == "" {
  105. return "", errors.New("加密数据为空")
  106. }
  107. block, err := des.NewTripleDESCipher(key)
  108. if err != nil {
  109. return "", err
  110. }
  111. origData := []byte(code)
  112. origData = PKCS5Padding(origData, block.BlockSize())
  113. blockMode := cipher.NewCBCEncrypter(block, key[:8])
  114. crypted := make([]byte, len(origData))
  115. blockMode.CryptBlocks(crypted, origData)
  116. encode := base64.StdEncoding.EncodeToString(crypted)
  117. return encode, nil
  118. }
  119. // 3DES解密
  120. func TripleDesDecrypt(args ...string) (string, error) {
  121. decode, key, err := getArgs(args)
  122. if err != nil {
  123. return "", err
  124. }
  125. if decode == "" {
  126. return "", errors.New("解密数据为空")
  127. }
  128. block, err := des.NewTripleDESCipher(key)
  129. if err != nil {
  130. return "", err
  131. }
  132. crypted, decodeErr := base64.StdEncoding.DecodeString(decode)
  133. if decodeErr != nil {
  134. return "", decodeErr
  135. }
  136. blockMode := cipher.NewCBCDecrypter(block, key[:8])
  137. origData := make([]byte, len(crypted))
  138. if len(crypted)%blockMode.BlockSize() != 0 {
  139. log.Println("ERROR", "TripleDesDecrypt: input not full blocks")
  140. return "", errors.New("解密失败")
  141. }
  142. blockMode.CryptBlocks(origData, crypted)
  143. origData = PKCS5UnPadding(origData)
  144. return string(origData), nil
  145. }
  146. //获取参数
  147. func getArgs(args []string) (string, []byte, error) {
  148. if len(args) == 0 {
  149. return "", nil, errors.New("参数不能为空")
  150. }
  151. origData := args[0]
  152. var crypt_key string
  153. if len(args) == 2 {
  154. crypt_key = args[1]
  155. } else {
  156. crypt_key = KEYS
  157. }
  158. key := []byte(crypt_key)
  159. return origData, key, nil
  160. }
  161. func ZeroPadding(ciphertext []byte, blockSize int) []byte {
  162. padding := blockSize - len(ciphertext)%blockSize
  163. padtext := bytes.Repeat([]byte{0}, padding)
  164. return append(ciphertext, padtext...)
  165. }
  166. func ZeroUnPadding(origData []byte) []byte {
  167. return bytes.TrimRightFunc(origData, func(r rune) bool {
  168. return r == rune(0)
  169. })
  170. }
  171. func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
  172. padding := blockSize - len(ciphertext)%blockSize
  173. padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  174. return append(ciphertext, padtext...)
  175. }
  176. func PKCS5UnPadding(origData []byte) []byte {
  177. length := len(origData)
  178. // 去掉最后一个字节 unpadding 次
  179. unpadding := int(origData[length-1])
  180. if length < unpadding || unpadding/8 > 3 {
  181. //解密的是错误的数据情况下,是没有填充的
  182. return []byte("")
  183. }
  184. return origData[:(length - unpadding)]
  185. }