Skip to content

AES加解密 in golang

go
package utils

import (
  "bytes"
  "crypto/aes"
  "crypto/cipher"
  "compress/gzip"
  "encoding/hex"
  "encoding/base64"
  "strings"
  "io/ioutil"
)

// gzip compress
func GZipBytes(data []byte) []byte {
  var buf bytes.Buffer
  gw := gzip.NewWriter(&buf)
  gw.Write(data)
  gw.Close()
  return buf.Bytes()
}

// gzip uncompress
func unGZipBytes(data []byte) []byte {
  var result []byte
  gr, err := gzip.NewReader(bytes.NewBuffer(data))
  if err != nil {} else {
    defer gr.Close()
    result, _ = ioutil.ReadAll(gr)
  }
  return result
}

func AES256Encrypt(plaintext []byte, key string, iv string, blockSize int) []byte {
  bKey := []byte(key)
  bIV := []byte(iv)
  bPlaintext := PKCS5Padding(plaintext, blockSize, len(plaintext))
  block, _ := aes.NewCipher(bKey)
  ciphertext := make([]byte, len(bPlaintext))
  mode := cipher.NewCBCEncrypter(block, bIV)

  if len(bPlaintext)%aes.BlockSize == 0 {
    mode.CryptBlocks(ciphertext, bPlaintext)
  }

  return ciphertext
}

func AES256Decrypt(ciphertext []byte, bKey []byte, bIV []byte) []byte {
  var result []byte
  block, _ := aes.NewCipher(bKey)
  mode := cipher.NewCBCDecrypter(block, bIV)
  plaintext := make([]byte, len(ciphertext))

  if len(ciphertext)%aes.BlockSize == 0 {
    mode.CryptBlocks(plaintext, ciphertext)
    result = PKCS5Trimming(plaintext)
  }

  return result
}

func PKCS5Padding(ciphertext []byte, blockSize int, after int) []byte {
  padding := (blockSize - len(ciphertext)%blockSize)
  padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  return append(ciphertext, padtext...)
}

func PKCS5Trimming(ciphertext []byte) []byte {
  var result []byte
  if len(ciphertext) > 0 {
    padding := ciphertext[len(ciphertext)-1]
    result = ciphertext[:len(ciphertext)-int(padding)]
  }
  return result
}

func PackBytesComEnc(b []byte, key string) []byte {
  iv := key[0:16]
  return AES256Encrypt(GZipBytes(b), key, iv, aes.BlockSize)
}

func PackBytesComDec(b []byte, key string) []byte {
  iv := key[0:16]
  return unGZipBytes(AES256Decrypt(b, []byte(key), []byte(iv)))
}

// in xml
func DecryptKey(b64CipherText string, hexKey string, hexIV string) string {
  decodeBytes, _ := base64.StdEncoding.DecodeString(b64CipherText)
  key, _ := hex.DecodeString(hexKey)
  iv, _ := hex.DecodeString(hexIV)
  return strings.TrimSpace(string(AES256Decrypt(decodeBytes, key, iv)))
}