印度包网
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.

266 lines
6.7 KiB

1 year ago
package util
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"io"
)
const (
Key = "iBszkjbOOZdaJbEp"
CurrentMode = 2
blocksize = 16
)
// AesEncrypt aes加密用不同的模式
func AesEncrypt(data []byte) []byte {
switch CurrentMode {
case 1:
return AesEncryptCBC(data)
case 2:
return AesEncryptECB(data)
case 3:
return AesEncryptCFB(data)
default:
return nil
}
}
func AesDecrypt(data []byte) (decrypted []byte, err error) {
switch CurrentMode {
case 1:
return AesDecryptCBC(data)
case 2:
return AesDecryptECB(data)
case 3:
return AesDecryptCFB(data)
default:
return nil, errors.New("unknow")
}
}
// AesEncryptCBC aes加密算法,采用cbc模式
func AesEncryptCBC(data []byte) []byte {
key := []byte(Key)
block, _ := aes.NewCipher(key)
blockSize := block.BlockSize() // 获取秘钥块的长度
data = Pkcs5Padding(data, blockSize) // 补全码
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式
encrypted := make([]byte, len(data)) // 创建数组
blockMode.CryptBlocks(encrypted, data) // 加密
// hex.EncodeToString(encrypted)
return []byte(base64.StdEncoding.EncodeToString(encrypted))
// return encrypted
}
// AesDecryptCBC 解密
func AesDecryptCBC(data []byte) (decrypted []byte, err error) {
data, err = base64.StdEncoding.DecodeString(string(data))
if err != nil {
decrypted = nil
return
}
key := []byte(Key)
block, _ := aes.NewCipher(key) // 分组秘钥
blockSize := block.BlockSize() // 获取秘钥块的长度
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 加密模式
decrypted = make([]byte, len(data)) // 创建数组
blockMode.CryptBlocks(decrypted, data) // 解密
decrypted = pkcs5UnPadding(decrypted) // 去除补全码
return
}
// AesDecrypt aes加密算法,采用ecb模式
func AesDecryptECB(origData []byte) (decrypted []byte, err error) {
// key := []byte(Key)
// tmp := ""
// tmp, err = url.QueryUnescape(string(origData))
// if err != nil {
// return
// }
origData, err = base64.StdEncoding.DecodeString(string(origData))
if err != nil {
return
}
cipher, _ := aes.NewCipher(generateKey())
decrypted = make([]byte, len(origData))
for bs, be := 0, cipher.BlockSize(); bs < len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Decrypt(decrypted[bs:be], origData[bs:be])
}
// trim := 0
// if len(decrypted) > 0 {
// trim = len(decrypted) - int(decrypted[len(decrypted)-1])
// }
// decrypted = decrypted[:trim]
decrypted = pkcs5UnPadding(decrypted)
// decrypted, err = base64.StdEncoding.DecodeString(string(decrypted))
// if err != nil {
// decrypted = nil
// return
// }
return
}
func AesDecryptECB1(origData []byte) (decrypted []byte, err error) {
origData, err = base64.StdEncoding.DecodeString(string(origData))
if err != nil {
return
}
cipher, _ := aes.NewCipher(generateKey())
decrypted = make([]byte, len(origData))
for bs, be := 0, cipher.BlockSize(); bs < len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Decrypt(decrypted[bs:be], origData[bs:be])
}
trim := 0
if len(decrypted) > 0 {
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
}
decrypted = decrypted[:trim]
decrypted, err = base64.StdEncoding.DecodeString(string(decrypted))
if err != nil {
decrypted = nil
return
}
return
}
func generateKey() (genKey []byte) {
key := []byte(Key)
genKey = make([]byte, 16)
copy(genKey, key)
for i := 16; i < len(key); {
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
genKey[j] ^= key[i]
}
}
return genKey
}
func AesEncryptECB(data []byte) []byte {
key := []byte(Key)
block, _ := aes.NewCipher(key)
// data = []byte(base64.StdEncoding.EncodeToString(data))
data = Pkcs5Padding(data, block.BlockSize())
decrypted := make([]byte, len(data))
size := block.BlockSize()
for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
block.Encrypt(decrypted[bs:be], data[bs:be])
}
return []byte(base64.StdEncoding.EncodeToString(decrypted))
}
func AesEncryptECB1(data []byte) []byte {
key := []byte(Key)
block, _ := aes.NewCipher(key)
data = []byte(base64.StdEncoding.EncodeToString(data))
// data = pkcs5Padding(data, block.BlockSize())
data = noPadding(data)
decrypted := make([]byte, len(data))
size := block.BlockSize()
for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
block.Encrypt(decrypted[bs:be], data[bs:be])
}
return []byte(base64.StdEncoding.EncodeToString(decrypted))
}
// AesEncryptCFB aes加密cfb模式
func AesEncryptCFB(origData []byte) (encrypted []byte) {
key := []byte(Key)
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
encrypted = make([]byte, blocksize+len(origData))
iv := encrypted[:blocksize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted[blocksize:], origData)
encrypted = []byte(base64.StdEncoding.EncodeToString(encrypted))
return
}
func AesDecryptCFB(data []byte) (decrypted []byte, err error) {
key := []byte(Key)
block, _ := aes.NewCipher(key)
if len(data) < blocksize {
decrypted = nil
err = errors.New("ciphertext too short")
return
}
encrypted, err := base64.StdEncoding.DecodeString(string(data))
if err != nil {
decrypted = nil
return
}
iv := encrypted[:blocksize]
encrypted = encrypted[blocksize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(encrypted, encrypted)
return
}
func ZeroPadding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{0}, padding) //用0去填充
return append(ciphertext, padtext...)
}
func ZeroUnPadding(origData []byte) []byte {
return bytes.TrimFunc(origData,
func(r rune) bool {
return r == rune(0)
})
}
func Pkcs5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func pkcs5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
// nopadding模式
func noPadding(src []byte) []byte {
count := blocksize - len(src)%blocksize
if len(src)%blocksize == 0 {
return src
} else {
return append(src, bytes.Repeat([]byte{byte(0)}, count)...)
}
}
// nopadding模式
func unNoPadding(src []byte) []byte {
for i := len(src) - 1; ; i-- {
if src[i] != 0 {
return src[:i+1]
}
}
}