RSA verification problem

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Hi all,

First of all, sorry if this is not the right place for asking.

I have the following problem:

I need to write a PHP script which verifies a RSA signature. The
problem is that this RSA signature is created using advapi.dll part of
MS CryptoAPI under Windows 2000 (VB6).
The Public key has the length of 1024bits and both together with the
signature are in Base64 format.  After spending some time researching
the topic I found out the following:
The Public Key created using MS CryptoAPI is in Base64 format.
Converted to byte array it has a length of 148 Bytes. Which are:
=B7    0 - 11 : Asymmetric algorithm used for encryption
=B7    12 - 15  : Modulus Bit length. Usually (0, 0, 4, 0) = 1024 bits /
8 = 128 bytes
=B7    16 - 19  :  Exponent, usually the default one is  (0, 1, 0, 1) =
65537
=B7    20 - 147  :  Modulus
I wrote a C# code which extracts modulus and exponent and encodes them
in Base64:

// Get Exponent
for (int i = 0; i < 4; i++)
{
bExponent[i] = bPublicKey[16 + i];
}

// Get Modulus Bit Length
for (int i = 0; i < 4; i++)
{
bModulusLength[i] = bPublicKey[12 + i];
}

Array.Reverse(bModulusLength);

iModulusLength = (bModulusLength[0] << 24) | (bModulusLength[1] << 16)
| (bModulusLength[2] << 8) | bModulusLength[3];

// Get Modulus
bModulus = new byte[iModulusLength / 8];
for (int i = 0; i < iModulusLength / 8; i++)
{
bModulus[i] = bPublicKey[20 + i];
}

Console.WriteLine("Exponent as Base64: " +
Convert.ToBase64String(bExponent) + "\n");

Console.WriteLine("Modulus as Base64: " +
Convert.ToBase64String(bModulus) + "\n");

After extracting the Modulus and the Exponent from the public key I
write the following PHP code (using Crypt_RSA package, part of PEAR
Framework) trying to decrypt the signature, which later must be
verified:

// include PEAR Crypt_RSA
require_once('Crypt\ RSA.php');

\$publicKey = Crypt_RSA_Key::factory(base64_decode(\$modulus),
base64_decode(\$exponent), "public"); if (PEAR::isError(\$publicKey)) {
echo "error: ", \$publicKey>getMessage(), "\ n"; }

// create new Crypt_RSA Object
\$rsa_obj = &Crypt_RSA::factory(); if (PEAR::isError(\$rsa_obj)) { echo
"error: ", \$rsa_obj->getMessage(), "\ n"; }

\$plaintext = \$rsa_obj->decrypt(\$signature, \$publicKey);

And here I am stuck. When I reverse the byte order of modulus and
exponent I got a public key which has a length of 1023bits. If I do not
reverse them I got  a public key which has a length of 1024bits and
after applying this key to decrypt function together with the signature
I do not receive the MD5 hash but a 126 byte long string.

I do not know if you have already had this problem trying to
synchronize signature verification between MS CryptoAPI, which
obviously does not follow the industry standards and other Crypto
providers=20

Any help will be really appreciated.

10x,
Paul