2

サーバーに通信しているデータを復号化しようとしています。スキームを使用して暗号化されたその特定の8桁の番号。暗号化キーと整合性キーを持っています。私はそれを解読する方法についてのドキュメントを持っています-

値は、カスタム暗号化スキームを使用して暗号化されます。暗号化スキームは、キー付きHMAC-SHA1アルゴリズムを使用して、一意のイベントIDに基づいてシークレットパッドを生成します。暗号化された値の長さは28バイトに固定されています。これは、16バイトの初期化ベクトル、8バイトの暗号文、および4バイトの整合性署名で構成されています。暗号化された値は、RFC 3548に従って、Webセーフのbase-64エンコードであり、パディング文字は省略されています。したがって、28バイトの暗号化された値は、38文字のWebセーフBase64文字列としてエンコードされます。値は次のように暗号化されます。

値xorHMAC-SHA1(encryption_key、initialization_vector)>

したがって、復号化は次のように計算します。

HMAC-SHA1(encryption_key、initialization_vector)

暗号化を逆にするために暗号化された値を持つxor。整合性ステージは4バイトを取ります

HMAC-SHA1(integrity_key、value || initialization_vector)>

ここで|| 連結です。

だから私は次の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

この問題を回避できません。ご意見をお聞かせください。

4

3 に答える 3

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;

これで問題が解決することを願っています。

于 2012-05-17T10:34:56.800 に答える
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));
于 2016-04-25T14:33:33.853 に答える
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
于 2012-05-29T17:03:58.220 に答える