如何将PHP的openssl des-ede3-cbc加密逻辑转为Go语言实现?
PHP 3DES-CBC加密逻辑的Go语言实现
原PHP代码的核心加密逻辑要点:
- 采用3DES-CBC模式加密
- 明文用**空字节(\x00)**填充至8字节的整数倍(DES块大小为8字节)
- 初始化向量(IV)固定为8个空字节
- 输出原始二进制加密结果,截取到填充后的明文长度
你的Go代码结果不一致的原因:
- 使用了随机生成的IV,与PHP固定全0IV不匹配
- 未对明文进行补零填充,若明文长度非8字节倍数会导致加密失败或结果不符
- 最终对加密结果做了Hex编码,而PHP输出的是原始二进制数据
修正后的Go实现代码
package main import ( "crypto/cipher" "crypto/des" "fmt" ) func tripleDESEncrypt(plainText, key []byte) ([]byte, error) { // 初始化3DES加密块 block, err := des.NewTripleDESCipher(key) if err != nil { return nil, err } // 补零填充:将明文长度补至8字节的整数倍 blockSize := des.BlockSize padding := blockSize - len(plainText)%blockSize if padding != blockSize { plainText = append(plainText, make([]byte, padding)...) } // 使用固定全0的IV,与PHP逻辑保持一致 iv := make([]byte, blockSize) // 切片默认初始化为全0字节 // CBC模式执行加密 cipherText := make([]byte, len(plainText)) mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(cipherText, plainText) // 截取到填充后的明文长度(与PHP的substr逻辑对齐) cipherText = cipherText[:len(plainText)] return cipherText, nil } func main() { // 替换为实际的明文和密钥(3DES密钥长度必须为24字节) message := []byte("hello world") key := []byte("1234567890abcdef12345678") encData, err := tripleDESEncrypt(message, key) if err != nil { fmt.Printf("加密失败:%v\n", err) return } // 若需要Hex编码输出(和你原Go代码的输出形式对齐),取消下面注释 // hexStr := hex.EncodeToString(encData) // fmt.Printf("Cipher text: %s\n", hexStr) // 原始二进制输出(对应PHP的OPENSSL_RAW_DATA参数) fmt.Printf("原始二进制加密结果长度:%d\n", len(encData)) }
关键细节说明
- 补零填充:严格复刻PHP的
str_repeat("\0", $l - strlen($message))逻辑,用空字节填充到块大小整数倍 - IV设置:Go中
make([]byte, des.BlockSize)生成的切片默认全为0字节,和PHP的"\0\0\0\0\0\0\0\0"完全匹配 - 加密模式:通过
cipher.NewCBCEncrypter实现标准CBC模式加密,对应PHP的des-ede3-cbc算法 - 结果处理:默认输出原始二进制数据,若需要Hex/Base64编码可自行添加(PHP中未指定
OPENSSL_RAW_DATA会默认Base64编码)
内容的提问来源于stack exchange,提问作者Jibon
相关产品推荐
相关产品推荐

