golang 和 php AES-128-CBC 加解密

268 阅读1分钟

最近对两个服务之间的数据传输进行加密解密。一个是golang服务。另外一个是 php服务。 go版本和 php 版本的记录一下.

ps: 代码基本是用 AI 生成的,给AI 点赞

package utils

import (
   "bytes"
   "crypto/aes"
   "crypto/cipher"
   "crypto/rand"
   "encoding/base64"
   "io"
)

func Encrypt(plainBytes []byte, key []byte) (string, error) {
   block, err := aes.NewCipher(key)
   if err != nil {
      return "", err
   }
   // 对于CBC模式,需要对数据进行填充
   plainBytes = pad(plainBytes, aes.BlockSize)
   ciphertext := make([]byte, aes.BlockSize+len(plainBytes))
   iv := ciphertext[:aes.BlockSize]
   if _, err := io.ReadFull(rand.Reader, iv); err != nil {
      return "", err
   }
   mode := cipher.NewCBCEncrypter(block, iv)
   mode.CryptBlocks(ciphertext[aes.BlockSize:], plainBytes)
   return base64.StdEncoding.EncodeToString(ciphertext), nil
}

func Decrypt(ct string, key []byte) (string, error) {
   block, err := aes.NewCipher(key)
   if err != nil {
      return "", err
   }
   ciphertext, err := base64.StdEncoding.DecodeString(ct)
   if err != nil {
      return "", err
   }
   if len(ciphertext) < aes.BlockSize {
      return "", err
   }
   iv := ciphertext[:aes.BlockSize]
   ciphertext = ciphertext[aes.BlockSize:]
   // CBC模式需要知道填充的大小
   mode := cipher.NewCBCDecrypter(block, iv)
   mode.CryptBlocks(ciphertext, ciphertext)
   plaintext := unpad(ciphertext)
   return string(plaintext), nil
}

// pad 对数据进行填充
func pad(buf []byte, blockSize int) []byte {
   padding := blockSize - (len(buf) % blockSize)
   padtext := bytes.Repeat([]byte{byte(padding)}, padding)
   return append(buf, padtext...)
}

func unpad(buf []byte) []byte {
   length := len(buf)
   if length == 0 {
      return buf
   }
   n := int(buf[length-1])
   return buf[:length-n]
}

php 版本

public function decryptAES($encryptedText)
{
    $cipher     = 'AES-128-CBC';
    $ciphertext = base64_decode($encryptedText);
    $ivSize     = openssl_cipher_iv_length($cipher);
    $iv         = substr($ciphertext, 0, $ivSize);
    $ciphertext = substr($ciphertext, $ivSize);

    $decrypted = openssl_decrypt($ciphertext, $cipher, $this->_cryptoKey, 1, $iv);
    if ($decrypted === false) {
        return false;
    }

    return $decrypted;
}

public function encryptAES($ciphertext)
{
    $cipher = 'AES-128-CBC';
    $ivSize = openssl_cipher_iv_length($cipher);
    $iv     = openssl_random_pseudo_bytes($ivSize);

    $ciphertext = $iv . $ciphertext;
    $decrypted  = openssl_encrypt($ciphertext, $cipher, $this->_cryptoKey, 1, $iv);

    return base64_encode($decrypted);
}