2012-05-17 5 views
2

Google 서버에 전달되는 데이터의 암호를 해독하려고합니다. 그것의 계획을 사용하여 암호화 된 특정 8 자리 숫자. 나는 나와 암호화 및 무결성 키를 가지고있다. 암호 해독 방법에 대한 설명서가 있습니다. -PHP의 암호 해독

값은 사용자 지정 암호화 체계를 사용하여 암호화됩니다. 암호화 체계는 키가있는 HMAC-SHA1 알고리즘을 사용하여 고유 한 이벤트 ID를 기반으로 보안 패드를 생성합니다. 암호화 된 값은 고정 길이가 28 바이트입니다. 이것은 16 바이트 초기화 벡터, 8 바이트의 암호문 및 4 바이트의 무결성 서명으로 구성됩니다. 암호화 된 값은 패딩 문자가 생략 된 RFC 3548, 에 따라 web-safe base-64로 인코딩됩니다. 따라서 28 바이트의 암호화 된 값은 이며 38 문자 웹 안전 기본 64 문자열로 인코딩됩니다. 값 로 암호화된다

값 XOR HMAC-SHA1 (encryption_key, initialization_vector)>

그렇게 복호화 계산 다음과

HMAC-SHA1 (encryption_key, initialization_vector)

과의 XOR의 암호화 된 값을 사용하여 암호화를 취소합니다. 무결성 스테이지

HMAC-SHA1 (integrity_key 가치 || initialization_vector)>

4 바이트 소요 || 연결입니다.

그래서 다음 PHP 코드를 작성했습니다.

$value= "[VALUE]"; //38 character base64 
$ekey=hextostr("[ENCRYPTIONKEY]"); //64 byte hex encoded key . 32 byte key 
$ikey=hextostr("[INTEGRITYKEY]"); //64 byte hex encoded key . 32 byte key 

$value=str_replace("-","+",$value); 
$value=str_replace("_","/",$value); 
$value=$value."=="; 
$dvalue=base64_decode($value); //Gets a 28 byte encrypted string. 

$initvec=substr($dvalue,0,16); 
$ciphertext=substr($dvalue,16,8); 
$integritysig=substr($dvalue,24,4); 

$pad=hash_hmac("sha1",$initvec,$ekey); //Generates 40 byte pad 

$uncipher=$ciphertext^$pad; 

print($uncipher); //This is 8 byte binary. Dumps some binary on screen. Result should be a 8 byte number 

이 문제를 해결할 수 없습니다. 제발 조언.

+0

당신은 "8 바이트 수는"당신이 그 뜻이야 말할? 아니면 10 진수의 숫자를 ASCII로 인코딩 한 것입니까? 또는 다른 것? – ndkrempel

+0

ASCII - 8 자리 숫자 –

+0

마지막으로 고유 한 이벤트 ID를 알고 있습니까? –

답변

1
$pad=hash_hmac("sha1",$initvec,$ekey); // returns a hexstring, but XOR interprets 
             // as ASCII string and converts to binary 
             // accordingly 

$ciphertext=substr($dvalue,16,8); // this is ASCII, converted to binary by XOR 

$uncipher=$ciphertext^$pad; // so the XOR operation is confused in interpretation. 

function bin2asc($in)#syntax - bin2asc("binary to convert"); 
{ 
    $out = ''; 
    for ($i = 0, $len = strlen($in); $i < $len; $i += 8) 
    { 
    $out .= chr(bindec(substr($in,$i,8))); 
    } 
    return $out; 
} 

$pad= hash_hmac("sha1",$initvec,$ekey, true); // now it will return in binary 
$pad = bin2asc($pad); 

$uncipher=$ciphertext^$pad; 

희망이 당신의 문제를 해결로 변경합니다.

+0

이 아닙니다. 이전에는 패드가 40 바이트 였으므로 20 바이트가되었습니다. 지금 strlen ($ uncipher) 8 반환하지만 화면에 반향 할 때 빈 표시합니다. 왜 지금 –

+0

을 시도하는지 잘 모르겠습니다 ... 우리는 ASCII 또는 2 진수로 둘 다 유지해야한다고 생각합니다. –

+0

nop .. strlen ($ pad)이 이제 3입니다. 암호화되지 않은 것도 3 바이트입니다. –

1

귀하의 게시 된 코드를 사용해보십시오이

$value= "[VALUE]"; //38 character base64 
$ekey=hextostr("[ENCRYPTIONKEY]"); //64 byte hex encoded key . 32 byte key 
$ikey=hextostr("[INTEGRITYKEY]"); //64 byte hex encoded key . 32 byte key 

$value=str_replace("-","+",$value); 
$value=str_replace("_","/",$value); 
$value=$value."=="; 
$dvalue=base64_decode($value); //Gets a 28 byte encrypted string. 

$initvec=substr($dvalue,0,16); 
$ciphertext=substr($dvalue,16,8); 
$integritysig=substr($dvalue,24,4); 

//here is the change 
$pad=hash_hmac("sha1",$initvec,$ekey, true); 

$uncipher=$ciphertext^$pad; 

print(hexdec(strToHex($uncipher))); //This is 8 byte binary. Dumps some binary on screen. Result should be a 8 byte number 
1

과 같아야이

function decrypt_google_winning_price($value, $ekey, $ikey, &$reason = '') { 
if (strlen($value) != 38) 
{ 
    $reason = "Wrong encrypted value length"; 
    return false; 
} 

$ekey = base64_decode($ekey); 
$ikey = base64_decode($ikey); 
$value = strtr($value, '-_,', '+/=') . "=="; 
$enc_value = base64_decode($value); //Gets a 28 byte encrypted string. 
if (strlen($enc_value) != 28) 
{ 
    $reason = "Wrong encrypted value length after base64_decode()"; 
    return false; 
} 

$iv = substr($enc_value, 0, 16);// initialization vector (16 bytes - unique to the impression) 
$p = substr($enc_value, 16, 8); // encryption key (32 bytes - provided at account set up) 
$sig = substr($enc_value, 24, 4);// integrity signature (4 bytes) 
$price_pad = hash_hmac("sha1", $iv, $ekey, true); 
$price = $p^$price_pad;// XOR 

$conf_sig = substr(hex2bin(hash_hmac("sha1", $price . $iv, $ikey)), 0, 4); 

if ($sig !== $conf_sig) 
{ 
    $reason = "Signature is not valid"; 
    return false; 
} 

return hexdec(bin2hex($price)); //This is 8 byte binary. Dumps some binary on screen. Result should be a 8 byte number 
} 


$value = "[VALUE]"; //38 character base64 
$ekey = "[ENCRYPTIONKEY]"; //64 byte hex encoded key . 32 byte key 
$ikey "[INTEGRITYKEY]"; //64 byte hex encoded key . 32 byte key 

var_dump(decrypt_google_winning_price($value, $ekey, $ikey));