我试着在go中重写一些用php5.6 (CodeIgniter)写的旧代码,但是我在go上被解密弄得头破血流。我设法从php to go解码MCRYPT_RIJNDAEL_128,其中iv的大小是16个字符,但我不能在256 - iv是32个字符。我不想使用go_mcrypt,因为它对libcrypt报头有严格的要求,所以我尝试使用CBC模式的go classic encrypt libs AES cipher,但在256上它抱怨IV的长度……php IV有32个字符,而不是预期的16个字符。
php部分工作得很好...
private $CIPHER_KEY = "12345678901234567890123456789012";
private function Encrypt($toEncrypt=null){
$iv_size = $this->ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = $this->ivKey = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$this->B64IV = base64_encode($iv);
return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->CIPHER_KEY, $toEncrypt, MCRYPT_MODE_CBC, $iv));
}这是PHP的结果:
KEY: 12345678901234567890123456789012
IV: Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1w=
ENC: Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1yATFjg26/Nav7cWtlJJL3djhUCND6KV8r/JL7owboKFA==
IV Size: 32IV包含在加密文本中...(有32个字符)
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); return 32func main(){
key := []byte("12345678901234567890123456789012")
iv,_ := base64.StdEncoding.DecodeString("Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1w=")
encText,_ := base64.StdEncoding.DecodeString("Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1yATFjg26/Nav7cWtlJJL3djhUCND6KV8r/JL7owboKFA==")
// iv := encText[:32] // also tried to get the iv from encoded string
fmt.Printf("Key Len: %d\nIV Len: %d\nENC Len: %d\n",len(key),len(iv),len(encText))
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
if len(encText) < aes.BlockSize {
panic("cipherText too short")
}
cipherText := encText[32:]
if len(cipherText)%aes.BlockSize != 0 {
panic("cipherText is not a multiple of the block size")
}
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(cipherText, cipherText)
cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize)
fmt.Printf("Dec: %s\n",cipherText)
}Key Len: 32 IV Len: 32 ENC Len: 64死机: cipher.NewCBCDecrypter: IV长度必须等于块大小
goroutine 1运行:crypto/cipher.NewCBCDeccrypter(0x10e7c20,0xc00009a030,0xc00008a000,0x20,0x42,0x0,0x0)
IV大小为32,但块大小为16。
发布于 2019-07-08 18:09:53
这在Linux中有效-对于任何有兴趣了解如何使用IV32字符进行解码的人
apt安装库加密-开发
去获取"github.com/tblyler/ go -mcrypt“
import (
"fmt"
"github.com/tblyler/go-mcrypt"
"encoding/base64"
)
const (
KEY = "12345678901234567890123456789012"
ENC = "Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1yATFjg26/Nav7cWtlJJL3djhUCND6KV8r/JL7owboKFA=="
)
func main(){
encText, _ := base64.StdEncoding.DecodeString(ENC)
iv := encText[:32]
toDecrypt := encText[32:]
fmt.Printf("Key Len: %d\n",len(KEY))
fmt.Printf("IV Len: %d\n",len(iv))
decText, err := mcrypt.Decrypt([]byte(KEY),iv,[]byte(toDecrypt))
if err != nil { panic(err) }
fmt.Printf("%s\n",decText)
}发布于 2019-07-08 18:15:31
在将代码从php 5.6移植到php 7.3时,我也遇到过类似的问题。我找到的最简单、最可靠的方法就是用php5.6解密所有的值,然后用新的格式重新解密。这是移动时一次性做的事情,但它省去了很多令人头疼的事情。
发布于 2019-07-08 23:07:43
我只是在我的MacOS上测试它,上面的代码是从mohade10.14.5开始工作的。
我使用MacPorts安装了libmcrypt
sudo端口安装库加密
mkdir mcrypt curl -o mcrypt/mcrypt.go https://raw.githubusercontent.com/tblyler/go-mcrypt/master/mcrypt.go
或者将其从您自己的src/github.com/tblyler/go-mcrypt复制到项目mcrypt文件夹
现在编辑mcrypt.go并添加C标志:
package mcrypt
/*
#cgo LDFLAGS: -L/opt/local/lib -lmcrypt
#cgo CFLAGS: -I/opt/local/include
#include <stdlib.h>
...修改上例中的import,在本地导入mcrypt版本,然后运行...
package main
import (
"fmt"
//"github.com/tblyler/go-mcrypt"
"./mcrypt"
"encoding/base64"
)运行代码时,它会添加有关链接的警告
ld: warning: building for macOS, but linking in object file (/var/folders/xz/7ng416ds5611ypt12c96g1_40000gn/T/go-link-754294955/go.o) built for
Key Len: 32
IV Len: 32
Abra Cadabrahttps://stackoverflow.com/questions/56926812
复制相似问题