98 lines
2.2 KiB
Go
98 lines
2.2 KiB
Go
/*
|
||
* @Date: 2021-03-11 17:25:13
|
||
* @LastEditors: viletyy
|
||
* @LastEditTime: 2021-04-26 23:17:26
|
||
* @FilePath: /yolk/crypt/des.go
|
||
*/
|
||
package crypt
|
||
|
||
import (
|
||
"bytes"
|
||
"crypto/des"
|
||
"encoding/hex"
|
||
"errors"
|
||
)
|
||
|
||
/*
|
||
* DES是一种对称加密算法,又称为美国数据加密标准.DES加密时以64位分组对数据进行加密,加密和解密都使用的是同一个长度为64位的密钥,
|
||
* 实际上只用到了其中的56位,密钥中的第8,16…64位用来作奇偶校验.DES有ECB(电子密码本)和CBC(加密块)等加密模式. DES算法的安
|
||
* 全性很高,目前除了穷举搜索破解外, 尚无更好的的办法来破解.其密钥长度越长,破解难度就越大. 填充和去填充函数.
|
||
*/
|
||
|
||
var desKey = []byte("2fa6c1e9")
|
||
|
||
type DesCrypt struct {
|
||
Key []byte
|
||
}
|
||
|
||
func NewDesCrypt(key ...[]byte) *DesCrypt {
|
||
if len(key) > 0 {
|
||
desKey = key[0]
|
||
}
|
||
return &DesCrypt{
|
||
Key: desKey,
|
||
}
|
||
}
|
||
|
||
// Des加密
|
||
func (crypt *DesCrypt) Encrypt(text string) (string, error) {
|
||
src := []byte(text)
|
||
block, err := des.NewCipher(crypt.Key)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
bs := block.BlockSize()
|
||
src = ZeroPadding(src, bs)
|
||
if len(src)%bs != 0 {
|
||
return "", errors.New("Need a multiple of the blocksize")
|
||
}
|
||
out := make([]byte, len(src))
|
||
dst := out
|
||
for len(src) > 0 {
|
||
block.Encrypt(dst, src[:bs])
|
||
src = src[bs:]
|
||
dst = dst[bs:]
|
||
}
|
||
return hex.EncodeToString(out), nil
|
||
}
|
||
|
||
// Des解密
|
||
func (crypt *DesCrypt) Decrypt(decrypted string) (string, error) {
|
||
src, err := hex.DecodeString(decrypted)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
block, err := des.NewCipher(crypt.Key)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
out := make([]byte, len(src))
|
||
dst := out
|
||
bs := block.BlockSize()
|
||
if len(src)%bs != 0 {
|
||
return "", errors.New("crypto/cipher: input not full blocks")
|
||
}
|
||
for len(src) > 0 {
|
||
block.Decrypt(dst, src[:bs])
|
||
src = src[bs:]
|
||
dst = dst[bs:]
|
||
}
|
||
out = ZeroUnPadding(out)
|
||
|
||
return string(out), nil
|
||
}
|
||
|
||
func ZeroPadding(ciphertext []byte, blockSize int) []byte {
|
||
padding := blockSize - len(ciphertext)%blockSize
|
||
padtext := bytes.Repeat([]byte{0}, padding)
|
||
|
||
return append(ciphertext, padtext...)
|
||
}
|
||
|
||
func ZeroUnPadding(origData []byte) []byte {
|
||
return bytes.TrimFunc(origData,
|
||
func(r rune) bool {
|
||
return r == rune(0)
|
||
})
|
||
}
|