I am trying to verify the authenticity of a message across PHP (phpseclib) and C#.
However, there seem to be some issues with the verification on the C# side.
What I have tried :
- Provide the public key to C# but make C# compute the hash and the signature then verify (Output: True)
- Change the hash to the one computed in PHP but make C# compute the signature then verify (Output: True)
- Make C# use PHP's computed hash and signature then verify (Output: False)
PHP Code :
//Load private key
$rsa = PublicKeyLoader::load("... private key ...", false);
//Set PKCS1 mode
$rsa->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1)->withHash("sha256");
//Generate and Convert the hash from 64 byte hex to 32 byte
$hash = pack("H*", hash("sha256", "test"));
//Sign the hash and encode it
$signed_hash = base64_encode($rsa->sign($hash));
//Encode the hash
$hash = base64_encode($hash);
C# Code :
static void Main()
{
//Create a new instance of RSA.
using (RSA rsa = RSA.Create())
{
//Load public key from XML string
rsa.FromXmlString("... public key ...");
//Create an RSAPKCS1SignatureDeformatter object and pass it the RSA instance
//to transfer the key information.
RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(rsa);
RSADeformatter.SetHashAlgorithm("SHA256");
//decode the hash
var hash = Convert.FromBase64String("SHA256 Hash As Base64");
var signedHash = Convert.FromBase64String("SHA256 Hash Signature As Base64");
//Verify the hash and display the results to the console.
if (RSADeformatter.VerifySignature(hash, signedHash))
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
}
}