Files
wechat_ipad_pro/clientsdk/android/aes.go

201 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package android
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"fmt"
log "github.com/sirupsen/logrus"
)
func padding(src []byte, blocksize int) []byte {
padnum := blocksize - len(src)%blocksize
pad := bytes.Repeat([]byte{byte(padnum)}, padnum)
return append(src, pad...)
}
func unpadding(src []byte) []byte {
n := len(src)
unpadnum := int(src[n-1])
return src[:n-unpadnum]
}
func EncryptAES(src []byte, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
src = padding(src, block.BlockSize())
blockSize := block.BlockSize()
if len(key) < blockSize {
return nil
}
blockmode := cipher.NewCBCEncrypter(block, key[:blockSize])
blockmode.CryptBlocks(src, src)
return src
}
func DecryptAES(src []byte, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
blockSize := block.BlockSize()
if len(key) < blockSize {
return nil
}
blockmode := cipher.NewCBCDecrypter(block, key[:blockSize])
blockmode.CryptBlocks(src, src)
src = unpadding(src)
return src
}
func AESEncrypt(src []byte, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
src = padding(src, block.BlockSize())
blockSize := block.BlockSize()
if len(key) < blockSize {
return nil
}
blockmode := cipher.NewCBCEncrypter(block, key[:blockSize])
blockmode.CryptBlocks(src, src)
return src
}
func AESDecrypt(src []byte, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
blockSize := block.BlockSize()
if len(key) < blockSize {
return nil
}
blockmode := cipher.NewCBCDecrypter(block, key[:blockSize])
blockmode.CryptBlocks(src, src)
src = unpadding(src)
return src
}
func AesEncrypt(RequestSerialize []byte, key []byte) []byte {
//根据key 生成密文
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
blockSize := block.BlockSize()
RequestSerialize = PKCS5Padding(RequestSerialize, blockSize)
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(RequestSerialize))
blockMode.CryptBlocks(crypted, RequestSerialize)
return crypted
}
func AesDecrypt(body []byte, key []byte) []byte {
// fmt.Printf("%x\n\n", body)
// fmt.Printf("%x\n\n", key)
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
origData := make([]byte, len(body))
blockMode.CryptBlocks(origData, body)
origData = PKCS5UnPadding(origData)
// fmt.Printf("%x\n", origData)
return origData
}
// =================== ECB ======================
func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {
cipher, _ := aes.NewCipher(generateKey(key))
length := (len(origData) + aes.BlockSize) / aes.BlockSize
plain := make([]byte, length*aes.BlockSize)
copy(plain, origData)
pad := byte(len(plain) - len(origData))
for i := len(origData); i < len(plain); i++ {
plain[i] = pad
}
encrypted = make([]byte, len(plain))
// 分组分块加密
for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
}
return encrypted
}
func AesDecryptECB(encrypted []byte, key []byte) (decrypted []byte) {
cipher, _ := aes.NewCipher(generateKey(key))
decrypted = make([]byte, len(encrypted))
//
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
}
trim := 0
if len(decrypted) > 0 {
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
}
return decrypted[:trim]
}
func generateKey(key []byte) (genKey []byte) {
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 CompressAndAes(RequestSerialize []byte, aeskey []byte) []byte {
compressed := DoZlibCompress(RequestSerialize)
return AesEncrypt(compressed, aeskey)
}
func DecompressAndAesDecrypt(body []byte, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
if len(body)%aes.BlockSize != 0 {
log.Error(fmt.Sprintf("crypto/cipher: data is not a multiple of the block size[BodyLength%v] [AesLength%v]", len(body), aes.BlockSize))
return nil
}
blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
origData := make([]byte, len(body))
blockMode.CryptBlocks(origData, body)
origData = PKCS5UnPadding(origData)
origData = DoZlibUnCompress(origData)
return origData
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
if length < unpadding {
return nil
}
return origData[:(length - unpadding)]
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
//填充
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}