2012-06-22 3 views
2

코드를 따르고 올바른 것으로 알고 있지만 제대로 작동하지 않습니다. PHP의 Mcrpyt로 데이터를 인코딩 한 다음 openssl 명령 줄 도구로 디코딩하려고합니다. 내가 인코딩 된 메시지에 IV를 추가openssl 명령 줄 도구를 사용하여 데이터 암호 해독

/* 
* Convert a normal ascii string to a hexadecimal string. 
* Complement of hexToString(). 
*/ 
function stringToHex($str) 
{ 
    $hex_str = ""; 
    for ($i = 0; $i < strlen($str); ++$i) 
    { 
     $hex_str .= sprintf("%02X", ord($str[$i])); 
    } 

    return $hex_str; 
} 


    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); 

    $block_size = mcrypt_get_block_size("rijndael-128", "cbc"); 
    $pad = $block_size - (strlen($data) % $block_size); 
    $data .= str_repeat(chr($pad), $pad); 

    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, "1234567812345678", $data, MCRYPT_MODE_CBC, $iv); 

    $message = stringToHex($iv) . base64_encode($encrypted); 

:

이 내 PHP 코드입니다. (사이즈 32)이 IV는 00000000000000000000000000000000입니다 예를 들어 말해, 그때 암호 해독에 대해 다음 명령을 사용하십시오 또한

openssl enc -d -aes-128-cbc -A -nosalt -K 31323334353637383132333435363738 -iv 00000000000000000000000000000000 -in file_in > file_out 

가 1234567812345678 16 진수가 31323334353637383132333435363738.입니다 참고하지만이 같은 오류 메시지가 계속 :

bad decrypt 1340:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:./crypto/evp/evp_enc.c:454:

누구?

미리 감사드립니다. 모든 사랑, Jori.

+0

아무도 없습니까? :-( 답변을 기다리는 중 – Jori

+2

코드 예제를 작성해야합니다. 누락 된 stringToHex 함수는 분명하지만 코드를 테스트 할 수는 없습니다. –

+0

아, 죄송합니다. 하지만 그것은 적절한 IV를 생성하기 때문에 문제가 있다고 생각하지 않습니다. 어쨌든 고마워! :-) – Jori

답변

2

글쎄, 나는 당신의 코드를 테스트했고 몇 가지 변화를했습니다.

1) openssl에 대한 입력은 앞에 붙어있는 IV가 아닌 암호문 만 포함해야합니다 (코드가 불완전하기 때문에 openssl로 처리하기 전에 실제로 암호문에서 IV를 제거했는지 확실하지 않았습니다).

2) openssl 명령에 실제로 Base64 디코딩을 수행하는 데 필요한 매개 변수 (-a)가 없습니다 (-A를 사용하면이 기능을 사용할 수 없습니다). 다시 말하지만, 설명이 불완전하기 때문에 메시지를 file_in에 저장하기 전에 Base64로 디코딩 한 것인지 확실하지 않았습니다.

코드를 테스트하기 위해 사용한 코드입니다 (웹 서버를 사용하지 않고 명령 줄에서 실행합니다).

<?php 

$data = " 
This is a test. This is only a test. 
Stack Overflow is collaboratively built and maintained 
by your fellow programmers. 
"; 
$keybin = "1234567812345678"; 


//$iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); 
$iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND); 
$block_size = mcrypt_get_block_size ("rijndael-128", "cbc"); 
$pad = $block_size - (strlen ($data) % $block_size); 
$data .= str_repeat (chr ($pad), $pad); 
$encrypted = mcrypt_encrypt (MCRYPT_RIJNDAEL_128, $keybin, $data, MCRYPT_MODE_CBC, $iv); 
$message = base64_encode ($encrypted); 

echo "CIPHERTEXT= " . $message . "\n"; 
echo "IV= " . bin2hex ($iv) . "\n"; 
echo "KEY= " . bin2hex ($keybin) . "\n"; 

echo "\nTest with:\n\necho $message | openssl enc -d -aes-128-cbc -nosalt -a -A -K " . bin2hex ($keybin) . " -iv " . bin2hex ($iv) . "\n\n"; 

?> 

기타 사소한 차이점은 PHP의 bin2hex를 사용한다는 것입니다.

그것은 같은 출력을 생성합니다 :

CIPHERTEXT= /e81Ua/0jxgff3j5GjKXaNilv5WqPYV7yRYy4AzsTUmGQeK0hcMjuUYp1Yrfthaox9zTI0DeDQT4fba+y/qTQahZpYRAKcZa209RVg4W1HrySfZPMRCxE+y8r8scL3Xmj+oMGFpS+cDo111OPqwHhNwWSHbMlsoJLvMr70ZiQmE= 
IV= 56c7c7248c68127cee8f0e54d89b4fc1 
KEY= 31323334353637383132333435363738 

Test with: 

echo /e81Ua/0jxgff3j5GjKXaNilv5WqPYV7yRYy4AzsTUmGQeK0hcMjuUYp1Yrfthaox9zTI0DeDQT4fba+y/qTQahZpYRAKcZa209RVg4W1HrySfZPMRCxE+y8r8scL3Xmj+oMGFpS+cDo111OPqwHhNwWSHbMlsoJLvMr70ZiQmE= | openssl enc -d -aes-128-cbc -nosalt -a -A -K 31323334353637383132333435363738 -iv 56c7c7248c68127cee8f0e54d89b4fc1 

당신이 가지고 오류를 (나쁜 해독은 디지털 봉투 루틴 EVP_DecryptFinal_ex)는 일반적으로 잘못된 키 또는 손상된 암호문을 의미한다. 귀하의 예제에서 문제가 prepended IV 및/또는 Base64 디코딩의 부족으로 인해 손상된 암호 텍스트라고 생각합니다.

+0

대단히 감사합니다! 문제는 사실 -A는 base64가 한 행을 디코딩하는 것을 의미한다고 생각한 것입니다. 이것을 -a -A로 변경하면 문제가 해결됩니다. – Jori

+0

당신은 환영합니다. 이것은 재미 있었다. :) –

1

openssl enc은 데이터가 블록 크기의 배수 인 경우 필수 패딩 블록을 제외하고 구현 한 PKCS # 5 패딩을 사용합니다. 16 바이트 (블록 크기)로 테스트 했으므로 chr(16)을 포함하는 다른 16 바이트를 추가해야합니다.