des.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package common
  2. import (
  3. "bytes"
  4. "crypto/cipher"
  5. "crypto/des"
  6. "encoding/hex"
  7. "fmt"
  8. )
  9. const (
  10. DES_CRYPT_KEY = "w$D5%8x@"
  11. DES_CRYPT_IV = "34RHn876"
  12. )
  13. type DES_CBC struct {
  14. }
  15. // 分组填充--填充对应长度的相同数字(1, 22, 333....)
  16. //data: 待分组数据, blockSize: 每组的长度
  17. func (d DES_CBC) PKCS7Padding(date []byte, blockSize int) (PaddingResult []byte) {
  18. // 获取数据长度
  19. length := len(date)
  20. // 获取待填充数据长度
  21. count := length % blockSize
  22. PaddingCount := blockSize - count
  23. // 在数据后填充数据
  24. PaddingDate := bytes.Repeat([]byte{byte(PaddingCount)}, PaddingCount)
  25. PaddingResult = append(date, PaddingDate...)
  26. return
  27. }
  28. // 分组移除
  29. func (d DES_CBC) PKCS7Unpadding(date []byte, blockSize int) (UnpaddingResult []byte) {
  30. length := len(date)
  31. temp := int(date[length-1])
  32. UnpaddingResult = date[:length-temp]
  33. return
  34. }
  35. //src: --明文/密文,需要分组填充,每组8byte
  36. //key: --秘钥 8byte
  37. //iv: --初始化向量 8byte 长度必须与key相同
  38. //加密
  39. func (d DES_CBC) DesCBCEncrypt(src []byte, key []byte, iv []byte) []byte {
  40. // 创建并返回一个使用DES算法的cipher.Block接口
  41. block, err := des.NewCipher(key)
  42. // 判断是否创建成功
  43. if err != nil {
  44. panic(err)
  45. }
  46. // 明文组数据填充
  47. paddingText := d.PKCS7Padding(src, block.BlockSize())
  48. // 创建一个密码分组为链接模式的, 底层使用DES加密的BlockMode接口
  49. blockMode := cipher.NewCBCEncrypter(block, iv)
  50. // 加密
  51. dst := make([]byte, len(paddingText))
  52. blockMode.CryptBlocks(dst, paddingText)
  53. return dst
  54. }
  55. // 解密:
  56. func (d DES_CBC) DesCBCDecrypt(src []byte, key []byte, iv []byte) []byte {
  57. // 创建并返回一个使用DES算法的cipher.Block接口
  58. block, err := des.NewCipher(key)
  59. if err != nil {
  60. panic(err)
  61. }
  62. // 创建一个密码分组为链接模式的, 底层使用DES解密的BlockMode接口
  63. blockMode := cipher.NewCBCDecrypter(block, iv)
  64. // 解密
  65. dst := make([]byte, len(src))
  66. blockMode.CryptBlocks(dst, src)
  67. // 分组移除
  68. dst = d.PKCS7Unpadding(dst, block.BlockSize())
  69. return dst
  70. }
  71. type DES_ECB struct {
  72. }
  73. //ECB加密
  74. func (d DES_ECB) EncryptDES_ECB(src, key string) string {
  75. data := []byte(src)
  76. keyByte := []byte(key)
  77. block, err := des.NewCipher(keyByte)
  78. if err != nil {
  79. panic(err)
  80. }
  81. bs := block.BlockSize()
  82. //对明文数据进行补码
  83. data = d.PKCS5Padding(data, bs)
  84. if len(data)%bs != 0 {
  85. panic("Need a multiple of the blocksize")
  86. }
  87. out := make([]byte, len(data))
  88. dst := out
  89. for len(data) > 0 {
  90. //对明文按照blocksize进行分块加密
  91. //必要时可以使用go关键字进行并行加密
  92. block.Encrypt(dst, data[:bs])
  93. data = data[bs:]
  94. dst = dst[bs:]
  95. }
  96. return fmt.Sprintf("%x", out)
  97. }
  98. //ECB解密
  99. func (d DES_ECB) DecryptDES_ECB(src, key string) string {
  100. data, err := hex.DecodeString(src)
  101. if err != nil {
  102. //fmt.Println(err)
  103. panic(err)
  104. }
  105. keyByte := []byte(key)
  106. block, err := des.NewCipher(keyByte)
  107. if err != nil {
  108. panic(err)
  109. }
  110. bs := block.BlockSize()
  111. if len(data)%bs != 0 {
  112. panic("crypto/cipher: input not full blocks")
  113. }
  114. out := make([]byte, len(data))
  115. dst := out
  116. for len(data) > 0 {
  117. block.Decrypt(dst, data[:bs])
  118. data = data[bs:]
  119. dst = dst[bs:]
  120. }
  121. out = d.PKCS5UnPadding(out)
  122. return string(out)
  123. }
  124. //明文补码算法
  125. func (d DES_ECB) PKCS5Padding(ciphertext []byte, blockSize int) []byte {
  126. padding := blockSize - len(ciphertext)%blockSize
  127. padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  128. return append(ciphertext, padtext...)
  129. }
  130. //明文减码算法
  131. func (d DES_ECB) PKCS5UnPadding(origData []byte) []byte {
  132. length := len(origData)
  133. unpadding := int(origData[length-1])
  134. return origData[:(length - unpadding)]
  135. }