2014-06-25 3 views
3

PHP의 사용 팩과는 다른 :펄 HMAC는 SHA256 나는이 PHP의 예처럼 SHA256 HMAC를 사용하여 펄에서 해시 생성 할 필요가

<?php 
$key = pack('H*','THIS_IS_KEY'); 
$str ='THIS IS DE ENCODED STRING'; 
echo strtoupper(hash_hmac('sha256',$str, $key)); 
?> 

를 내가 얻을 : 601B7C81389A37FC83C05275138280E8788CF9108528BC75D5C09CEA75904D5E

을하지만 난에서 동일한 작업을 수행하는 경우 Perl 스크립트 :

use Digest::SHA qw(hmac_sha256_hex); 
my $key = pack('H*','THIS_IS_KEY'); 
my $str ='THIS IS DE ENCODED STRING'; 
print uc(hmac_sha256_hex($str, $key)); 
exit; 

내가 얻을 : C683FD81DEFB7CDA3C031F5280682E80851FDC246310DB8C44057BC636를 4454E0

필자가 핵심 패키지 인 Perl이나 PHP를 포장하지 않으면 같은 결과를 얻습니다. 불행히도 PHP "pack"을 사용하는 예제와 정확히 같은 결과를 생성해야합니다.

누군가 해결책을 찾도록 도와 주시면 감사하겠습니다. 사전에

덕분에

웰치

+2

두 경우 모두 * 실제 * 키는 무엇입니까? 즉,'pack '과 관련된 문제는 무엇입니까? 다른 hmac 함수가 그것을 (또는 str) 다르게 처리합니까? – user2864740

+1

PHP 오류 로깅이 충분히 높다고 가정하면, 당신이 제공 한 PHP 코드는'pack' 사용에 관한 몇 가지 경고를 발산해야합니다. 두 스크립트 모두에서'$ key = 1234'를 하드 코딩 해보십시오. 그리고 생성 된 다이제스트는 동일하다는 것을 알아 두십시오. HMAC SHA256의 PHP 및 Perl 구현은 모두 동일하게 작동합니다. 그것은 서로 다른'pack' 구현체입니다! – tobyink

+0

안녕하세요, 예, 문제는 팩 기능 구현에 있음을 확인합니다. 문제는 Perl을 코딩하고 있고 다른 쪽의 응용 프로그램이 PHP 메소드를 사용하고 있는데 데이터를 전달할 때 유효성을 검사하지 않았기 때문입니다. 필자는 Perl 스크립트를 제어 할 수 있기 때문에 양쪽 플랫폼 중 어느 것이 좋든 나쁘 든 동일한 결과를 얻는 방법을 찾아야합니다. 웨일스 사람 – Welch

답변

1

코드는 pack() 기능이 실제로 어떻게 작동하는지 이해하지 못합니다. 열쇠는 PHP와 Perl 스크립트간에 다른 점입니다. 따라서이 계산으로 줄이자. 여기에 간단한 PHP 프로그램입니다 : 여기

00000000 0000 0000 000e 

비슷한 펄 프로그램입니다 : 우리가 php | hexdump에 그 반향 경우

<?php 
    $key = pack('H*', 'THIS_IS_KEY'); 
    echo $key; 
?> 

, 우리가 얻을

my $key = pack('H*', 'THIS_IS_KEY'); 
print $key; 

그리고 우리는 perl | hexdump에 그 반향 경우 , 우리는 다음을 얻습니다 :

0000000 2cd1 cff2 204e 

두 가지 크게 다른 키입니다. 두 경우 모두 pack() 호출은 H* 형식을 사용하므로 pack()은 제한없는 16 진수 문자열 (16 진수 문자 0-9A-F를 포함하는 문자열)을받을 것으로 예상됩니다. 문제는 'THIS_IS_KEY'이 16 진수 값의 시퀀스가 ​​아니라는 것입니다 ('E'제외). 당신이 php 바이너리 자체를 통해 테스트 코드를 실행하면, 당신은 또한이 라인을 볼 수 있습니다 :

이 오류가 발생합니다 'E'를 제외한 모든 문자, 그리고 당신의 진수 출력 점에 유의하는 것이
PHP Warning: pack(): Type H: illegal hex digit T in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit H in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit I in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit S in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit _ in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit I in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit S in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit _ in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit K in - on line 2 
PHP Warning: pack(): Type H: illegal hex digit Y in - on line 2 

주, 모든 캐릭터는 'E'의 경우을 제외하고는 null 니블 으로 변환됩니다. Perl은 실제로 말도 안되는 문자를 만들어 사용하려고하는 일종의 표현으로 변환하려고합니다 (예 : 'K'는 4가됩니다. F 이후의 다섯 번째 문자이므로 16 진수로 14에 해당합니다). 어쨌든 형식과 일치하지 않는 문자열을 전달해야하는 동작은 정의되지 않았습니다.

그렇다면 솔루션은 무엇입니까?

글쎄, 'THIS_IS_KEY'을 키로 유지해야한다면, 해당하는 Perl 키는 '000000000E0'입니다. 예제 키가 키 값을 나타내는 경우에만 일반적으로 Perl 스크립트에서 PHP 키의 16 진수가 아닌 문자를 '0'으로 바꿉니다.PHP는 16 진수 문자열에서 16 진수가 아닌 문자를 '0'으로 처리하는 것으로 보입니다.

실제 해결 방법은 문자열 키를 16 진수 표현으로 변환하거나으로 전달하기 전에 16 진수 값을 키로 사용하십시오. 나는 키 선택의 세부 사항이나 왜 "키"가 어쨌든 포장되는 이유를 모른다. 코드의 SHA256 부분은 바이트 문자열을 키로 사용합니다. 두 스크립트가 동일한 순서의 바이트를 사용하는 한 염두에두면 바로 ASCII 키가 될 수 있습니다.