I'm trying to implement a routine in order to use the following data verification mechanism:

- - A GET parameter is received (Base16) that needs to be converted to a binary string;

- This binary string needs to be decrypted with a RSA key from a binary file that has been received earlier;

- The resulting SHA hash will be used to verify the complete call.

The binary file for the RSA key, has the following structure:

- - The first 4 bytes (in bigEndian) contain the RSA key size in bits.

- The next byte contains a 1 or 0 value, to indicate transmission in bigEndian (1) or littleEndian (0).

- The next byte sequence (the number of bytes is specified by the key size) reflects the RSA key modulus in bigEndian

- The final byte sequence (the number of bytes is also specified by the key size) reflects the RSA key exponent in bigEndian

- Code: Select all
`function binToInt($input)`

{

$len = strlen($input);

$result = 0;

for ($i=0; $i < $len; $i++) {

$result += ord($input[$i]) << (($len-$i-1)*8);

}

return $result;

}

$keyContent = file_get_contents('keyfile.bin');

$size = binToInt(strrev(substr($keyContent, 0, 4))) / 8;

$bigEndian = binToInt(strrev(substr($keyContent, 4, 1)));

$modulus = strrev(substr($keyContent, 5, $size));

$exponent = strrev(substr($keyContent, 5 + $size, $size));

With these values I create the RSA as follows, based on the only example that I found that actually resulted in a valid key:

- Code: Select all
`$rsa = new Crypt_RSA();`

$rsa->modulus = new Math_BigInteger(($modulus), 256);

$rsa->exponent = new Math_BigInteger(($exponent), 256);

$rsa->publicExponent = new Math_BigInteger(($exponent), 256);

$rsa->k = strlen($rsa->modulus->toBytes());

If at this moment I export the public key (as a check), I do get output that seems to present a valid key:

-----BEGIN PUBLIC KEY-----

MIIBCAKBgQDTZjlab/zwVMqfbuLba4kyc/STDKlKIS+O8iXeHm4cWodjLF2RSLzmFY9XqT/Apleg

[ ... ]

+tfQIRcT9QuIaSyHxfluo9N4bzMvQl/C6pgDRq+UDN3t4DrnxlAUPw==

-----END PUBLIC KEY-----

Finally the query string parameter is being read like:

- Code: Select all
`/*`

* hex2bin

* Convert a hex-string to binary-string (the way back from bin2hex)

* (a found function that seems to do the trick)

*/

function hex2bin($h)

{

if (!is_string($h)) return null;

$r='';

for ($a=0; $a<strlen($h); $a+=2) {

$r .= chr(hexdec($h{$a}.$h{($a+1)}));

}

return $r;

}

$encrypted = hex2bin($_GET['encryptedHash']);

// Neither is working:

// $encrypted = hex2bin(strrev($_GET['encryptedHash']));

However, when I'm trying the most crucial step, the decryption fails no matter what I try:

- Code: Select all
`$rsa->decrypt($encrypted);`

$rsa->decrypt(strrev($encrypted));

It always returns FALSE and a notice (Decryption error in phpseclib0.2.2/Crypt/RSA.php on line 1819).

Just as a reference, the failing check on line 1818 is: if ($lHash != $lHash2) {

I'm working at this moment on OSX 10.6.8 but the code should be able to work on Debian (just in case this matters for the bigEndian vs. littleEndian)

It's getting very frustrating, especially as I (perhaps very misplaced) think I'm very close...

Any help or suggestion is more than welcome.

Thanks in advance

Philip