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.
265 lines
6.7 KiB
265 lines
6.7 KiB
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] |
|
} |
|
} |
|
}
|
|
|