Aditya Singh - 1 year ago 61

PHP Question

I am trying to decrypt data being communicated to our server. Its a certain 8 digit number which is encrypted using a scheme. I have the encryption and integrity keys with me. I have a documentation on how to decrypt it which says -

The value is encrypted using a custom encryption scheme. The

encryption scheme uses a keyed HMAC-SHA1 algorithm to generate a

secret pad based on the unique event ID. The encrypted value has a

fixed length of 28 bytes. It is comprised of a 16-byte initialization

vector, 8 bytes of ciphertext, and a 4-byte integrity signature. The

encrypted value is web-safe base-64-encoded, according to RFC 3548,

with padding characters omitted. Thus, the 28-byte encrypted value is

encoded as a 38 character web-safe base-64 string. The value is

encrypted as:

value xor HMAC-SHA1(encryption_key, initialization_vector)>

so decryption calculates:

HMAC-SHA1(encryption_key, initialization_vector)

and xor's with the encrypted value to reverse the encryption. The

integrity stage takes 4 bytes of

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

where || is concatenation.

So i wrote the following PHP Code.

`$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

Unable to get around this problem. Please advice.

Answer Source

```
$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.
```

try changing it to,

```
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;
```

hope this solve your problem.