package utils import ( "applet/app/cfg" "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" "encoding/json" "fmt" ) func AesEncrypt(rawData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() rawData = PKCS5Padding(rawData, blockSize) // rawData = ZeroPadding(rawData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) encrypted := make([]byte, len(rawData)) // 根据CryptBlocks方法的说明,如下方式初始化encrypted也可以 // encrypted := rawData blockMode.CryptBlocks(encrypted, rawData) return encrypted, nil } func AesDecrypt(encrypted, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) rawData := make([]byte, len(encrypted)) // rawData := encrypted blockMode.CryptBlocks(rawData, encrypted) rawData = PKCS5UnPadding(rawData) // rawData = ZeroUnPadding(rawData) return rawData, 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(rawData []byte) []byte { length := len(rawData) unPadding := int(rawData[length-1]) return rawData[:(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...) } func PKCS5UnPadding(rawData []byte) []byte { length := len(rawData) // 去掉最后一个字节 unPadding 次 unPadding := int(rawData[length-1]) return rawData[:(length - unPadding)] } // 填充0 func zeroFill(key *string) { l := len(*key) if l != 16 && l != 24 && l != 32 { if l < 16 { *key = *key + fmt.Sprintf("%0*d", 16-l, 0) } else if l < 24 { *key = *key + fmt.Sprintf("%0*d", 24-l, 0) } else if l < 32 { *key = *key + fmt.Sprintf("%0*d", 32-l, 0) } else { *key = string([]byte(*key)[:32]) } } } type AesCrypt struct { Key []byte Iv []byte } func (a *AesCrypt) Encrypt(data []byte) ([]byte, error) { aesBlockEncrypt, err := aes.NewCipher(a.Key) if err != nil { println(err.Error()) return nil, err } content := pKCS5Padding(data, aesBlockEncrypt.BlockSize()) cipherBytes := make([]byte, len(content)) aesEncrypt := cipher.NewCBCEncrypter(aesBlockEncrypt, a.Iv) aesEncrypt.CryptBlocks(cipherBytes, content) return cipherBytes, nil } func (a *AesCrypt) Decrypt(src []byte) (data []byte, err error) { decrypted := make([]byte, len(src)) var aesBlockDecrypt cipher.Block aesBlockDecrypt, err = aes.NewCipher(a.Key) if err != nil { println(err.Error()) return nil, err } aesDecrypt := cipher.NewCBCDecrypter(aesBlockDecrypt, a.Iv) aesDecrypt.CryptBlocks(decrypted, src) return pKCS5Trimming(decrypted), nil } func pKCS5Padding(cipherText []byte, blockSize int) []byte { padding := blockSize - len(cipherText)%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(cipherText, padText...) } func pKCS5Trimming(encrypt []byte) []byte { padding := encrypt[len(encrypt)-1] return encrypt[:len(encrypt)-int(padding)] } // AesAdminCurlPOST is 与后台接口加密交互 func AesAdminCurlPOST(aesData string, url string) ([]byte, error) { adminKey := cfg.Admin.AesKey adminVI := cfg.Admin.AesIV crypto := AesCrypt{ Key: []byte(adminKey), Iv: []byte(adminVI), } encrypt, err := crypto.Encrypt([]byte(aesData)) if err != nil { return nil, err } // 发送请求到后台 postData := map[string]string{ "postData": base64.StdEncoding.EncodeToString(encrypt), } fmt.Println(adminKey) fmt.Println(adminVI) fmt.Println("=======ADMIN请求=====") fmt.Println(postData) postDataByte, _ := json.Marshal(postData) rdata, err := CurlPost(url, postDataByte, nil) fmt.Println(err) if err != nil { return nil, err } fmt.Println(rdata) pass, err := base64.StdEncoding.DecodeString(string(rdata)) if err != nil { return nil, err } fmt.Println(pass) decrypt, err := crypto.Decrypt(pass) fmt.Println(err) if err != nil { return nil, err } return decrypt, nil }