在PHP中解密

时间:2012-05-17 01:21:30

标签: php encryption sha1 hmac

我正在尝试解密传输到我们服务器的数据。它是一个8位数字,使用方案加密。我有加密和完整性密钥。我有一个关于如何解密它的文档 -

  

使用自定义加密方案对值进行加密。该   加密方案使用密钥HMAC-SHA1算法生成   基于唯一事件ID的秘密填充。加密值有一个   固定长度为28个字节。它由16字节的初始化组成   向量,8个字节的密文和4字节的完整性签名。该   根据RFC 3548,加密值是web-safe base-64编码的,   填充字符省略。因此,28字节的加密值是   编码为38个字符的Web安全base-64字符串。价值是   加密为:

     

值xor HMAC-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

无法解决此问题。请指教。

3 个答案:

答案 0 :(得分: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;
希望这能解决你的问题。

答案 1 :(得分: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

答案 2 :(得分:1)

试试这个

var externalString = "funcs={myFunction:function(param){console.log(param);} , otherFunction:function(){x=10+10; return x;}};"

var functions=eval(externalString);

functions.myFunction('test'); // this writes to console
alert(functions.otherFunction());