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);
我正在尝试在 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);