Расшифровать AES-CBC-256 Mcrypt_RIJNDAEL, зашифрованный в PHP, расшифровать на GOLang - PullRequest
0 голосов
/ 08 июля 2019

Я пытаюсь переписать какой-то старый код, созданный в php5.6 (CodeIgniter) на ходу, но я бьюсь головой с расшифровкой на ходу.Мне удалось декодировать MCRYPT_RIJNDAEL_128 из php to go, где размер iv равен 16 символам, но я не могу сделать это для 256 - iv равен 32. Я не хочу использовать go_mcrypt, потому что это строго по заголовкам libcrypt, поэтому я попыталсяиспользуя go classic encrypt lib AES-шифр с режимом CBC, но на 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: 32

IV включен в зашифрованный текст ... (и имеет 32 символа)

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\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)

}

Ключ Len: 32 IV. Len: 32 ENC. Len: 64.0x42, 0x0, 0x0)

Размер IV равен 32, но размер блока равен 16.

Ответы [ 3 ]

0 голосов
/ 08 июля 2019

Я играл с подобной проблемой при переносе кода с php 5.6 на php 7.3. Самый простой и надежный способ, который я нашел, - это просто расшифровать все значения с помощью php 5.6, а затем перекодировать в новом формате, который работает хорошо. Это единовременное занятие при переезде, но оно избавляет от многих головных болей.

0 голосов
/ 08 июля 2019

Я только что протестировал его на моем MacOS, приведенный выше код работает с Mohave 10.14.5.

Я использовал MacPorts для установки libmcrypt

порт sudo установить libmcrypt

мкдир макрипт 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>
...

изменить импорт из приведенного выше примера для локального импорта версии 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 Cadabra
0 голосов
/ 08 июля 2019

Это работает в Linux - для любого, кто придумал, как декодировать с помощью IV 32 символа

apt install libmcrypt-dev

иди "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)
}
...