PHP 来自 Golang 给定数据的 AES-256-CBC 加密

PHP AES-256-CBC encryption from Golang given data

我正在尝试在 PHP 中实现 AES-256-CBC 加密。我从 Golang 代码中得到了一个数据输出。我尝试在 PHP 中获取加密值,但总是失败 我尝试解密它。

这是我在 Golang 中的加解密代码

var key = "abcdabcdabcdabcd"

func main() {
    str := "hello world"
    fmt.Printf("Origin Data : %v\n", str)
    encryptStr := Encrypt(str)
    fmt.Printf("Encrypt Data : %v\n", encryptStr)
    decryptstr := Decrypt(encryptStr)
    fmt.Printf("Decrypt Data : %v\n", decryptstr)
}

func Encrypt(str string) string {

    data := PKCS5Padding([]byte(str))
    iv := make([]byte, 16)
    rand.Read(iv)

    blockCipher, err := aes.NewCipher([]byte(key))
    if err != nil {
        panic(err)
    }

    c := cipher.NewCBCEncrypter(blockCipher, iv)
    c.CryptBlocks(data, data)
    data = append(iv, data...)

    return hex.EncodeToString(data)
}

func Decrypt(str string) string {

    origin, _ := hex.DecodeString(str)

    iv := origin[:16]
    data := origin[16:]

    block, err := aes.NewCipher([]byte(key))
    if err != nil {
        panic(err)
    }

    c := cipher.NewCBCDecrypter(block, iv)
    c.CryptBlocks(data, data)

    return string(data)

}

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

并且我可以获得输出:

Origin Data : hello world
Encrypt Data : efb5e55e9d2d15e6a61dcfeef322b0da839674e76666962d41f6a00a04d84adf
Decrypt Data : hello world

运行 here

中的代码

我的php代码

public function Decode(){

        //encrypt string from golang
        $strFromGolang = "efb5e55e9d2d15e6a61dcfeef322b0da839674e76666962d41f6a00a04d84adf";
        $decode = hex2bin($strFromGolang);

        $key = "abcdabcdabcdabcd";
        //format
        $data = substr($decode, 16);
        $iv = substr($decode, 0, 16);

        $decrypt = openssl_decrypt($data, 'aes-256-cbc', $key, 0, $iv);
        var_dump($decrypt);
    }

和 $decrypt 得到的值 false

如何修复我的 php 代码,使 $decrypt 解密成功?

您有两个问题:

首先,GO 加密使用的不是 AES-256-CBC,而是 AES-128-CBC。我不确定如何在 GO 端解决此问题,但在 PHP 端,只需使用 AES-128-CBC 作为密码字符串即可。

其次,PHP 解密期望对 BASE64 编码的文本进行操作,而不是原始二进制字符串。要像您的情况一样解密原始二进制字符串,您需要传递可选的 OPENSSL_RAW_DATA 标志:

$decrypt = openssl_decrypt($data, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);