doulang9953 2019-07-07 23:12
浏览 256

在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.

  • 写回答

3条回答

  • douliao7354 2019-07-08 10:09
    关注

    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)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?