在GOLang上用PHP解密的AES-CBC-256 Mcrypt_RIJNDAEL解密

I try to rewrite some old code made in php5.6 (CodeIgniter) in go, but I'm banging my head with decryption on go. I managed to decode MCRYPT_RIJNDAEL_128 from php to go, where the iv size is 16 characters, but I can't do it on 256 - iv is 32. I don't want to use go_mcrypt because that's strict on libcrypt headers, so I tried using go classic encrypt libs AES cipher with CBC mode, but on 256 it complains about IV length... The php IV has 32 characters not 16 as expected..

The php part works well...

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));
    }

this is the PHP result:

KEY: 12345678901234567890123456789012
IV: Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1w=
ENC: Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1yATFjg26/Nav7cWtlJJL3djhUCND6KV8r/JL7owboKFA==
IV Size: 32

IV is included in the encrypted text... (and has 32 chars)

mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); return 32
func 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
IV  Len: %d
ENC Len: %d
",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
",cipherText)

}

Key Len: 32 IV Len: 32 ENC Len: 64 panic: cipher.NewCBCDecrypter: IV length must equal block size

goroutine 1 [running]: crypto/cipher.NewCBCDecrypter(0x10e7c20, 0xc00009a030, 0xc00008a000, 0x20, 0x42, 0x0, 0x0)

IV size is 32 but the block size is 16.

dqm88684
dqm88684 OK-我重新阅读了文档,并且AES-256仅使用128字节的IV(16个字符)。AES是Rijndael的一种变体,具有128位的固定块大小,密钥大小为128、192或256位。Rijndael文档指定的块和密钥大小为32位的倍数,最小为128位,最大为256位,因此混淆AES不是RIJNDAEL-只是一个变体。我猜唯一的解决方案是解密php中的敏感数据并使用128字节IV对其进行加密。有谁知道另一个库-与RIJNDAEL250兼容,可以处理256字节(32个字符)的IV?
一年多之前 回复

3个回答



这在Linux中有效-适用于对如何使用IV 32个字符进行解码的人</ p>


apt install libmcrypt-dev </ p>

获取“ github.com/tblyler/go-mcrypt”


 <代码>导入(
“ fmt”
“ github.com/tblyler/go-mcrypt"
” encoding / base64“

const(\ n KEY =“ 12345678901234567890123456789012”
ENC =“ Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1yATFjg26 / Nav7cWtlJJL3djhUCND6KV8r / JL7owboKFA ==
)(n)
) := encText [:32]
toDecrypt:= encText [32:]

fmt.Printf(“ Key Len:%d
”,len(KEY))
fmt.Printf(“ IV Len: %d
“,len(iv))

decText,err:= mcrypt.Decrypt([] byte(KEY),iv,[] byte(toDecrypt))
if err!= nil {panic( err)}

fmt.Printf(“%s
”,decText)
}
</ code> </ pre>
</ div>

展开原文

原文

This works in Linux - for anyone courious how to decode with IV 32 characters

apt install libmcrypt-dev

go get "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
",len(KEY))
    fmt.Printf("IV  Len: %d
",len(iv))

    decText, err := mcrypt.Decrypt([]byte(KEY),iv,[]byte(toDecrypt))
    if err != nil { panic(err) }

    fmt.Printf("%s
",decText)
}



将代码从php 5.6传输到php 7.3时,我一直在玩类似的问题。 我发现的最简单,最可靠的方法就是使用php 5.6解密所有值,然后使用效果很好的新格式进行解密。 过去,这是一回事,但可以省去很多麻烦。</ p>
</ div>

展开原文

原文

I've been playing with a similar issue, when transporting code from php 5.6 to php 7.3. The easiest and most reliable way I have found is just to decrypt all the values with php 5.6 and then recrypt with the new format that works well. It's a one time thing to do when moving over, but it saves a lot of headaches.

I just test it from my MacOS, the above code is working from Mohave 10.14.5.

I used MacPorts to install libmcrypt

sudo port install libmcrypt

mkdir mcrypt curl -o mcrypt/mcrypt.go https://raw.githubusercontent.com/tblyler/go-mcrypt/master/mcrypt.go

or copy it from your own src/github.com/tblyler/go-mcrypt to project mcrypt folder

now edit mcrypt.go and add the C flags:

package mcrypt

/*
#cgo LDFLAGS: -L/opt/local/lib -lmcrypt
#cgo CFLAGS: -I/opt/local/include
#include <stdlib.h>
...

modify import from above example to import mcrypt version locally, and run it...

package main

import (
  "fmt"
//"github.com/tblyler/go-mcrypt"
  "./mcrypt"
  "encoding/base64"
)

when running the code it adds a warning about linking

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 Cadabra
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐