3

I am attempting to verify an OpenSSL signature (created using openssl_sign with SHA1 in PHP) using C# RSACryptoProvider.VerifyData. It is returning false using the correct public key certificate.

Any idea about how to do this successfully?

EDIT:

I attempted to verify the OpenSSL SHA1 signature using BouncyCastle with the following code but verification is failing. Are the signatures calculated differently? How can I create a signature with OpenSSL that is verifiable by .NET?

byte[] signatureBytes = UTF8Encoding.Default.GetBytes(signature);
  byte[] dataBytes = UTF8Encoding.Default.GetBytes(data);

  StreamReader sr = new StreamReader(Path.Combine(@"C:\test", @"test\test.crt"));
  PemReader pr = new PemReader(sr);

  Org.BouncyCastle.X509.X509Certificate cert = (Org.BouncyCastle.X509.X509Certificate)pr.ReadObject();

  ISigner sig = SignerUtilities.GetSigner("SHA1WithRSAEncryption");
  sig.Init(false, cert.GetPublicKey());
  sig.BlockUpdate(dataBytes, 0, dataBytes.Length);
  if (sig.VerifySignature(signatureBytes)) {
    Console.WriteLine("all good!");
  }

PHP Code:

function signTokenWithPrivateKey($message, $keyLocation) {
  try {
    if (file_exists($keyLocation)) {
      $privateKey= openssl_get_privatekey(file_get_contents($keyLocation));

      $signature = '';
      if (!openssl_sign($message, $signature, $privateKey)) {
        die('Failed to encrypt');
      }

      openssl_free_key($privateKey);
    }
  }
  catch (Exception $ex) {

  }

  return $signature;
}
theringostarrs
  • 11,940
  • 14
  • 50
  • 63
  • hi, can you include the key & signature you want to verify in the question? the php code may help too – russau Aug 31 '12 at 01:40
  • Theres the PHP code. Will post key and signature at later date. – theringostarrs Aug 31 '12 at 02:52
  • @theringostarrs Did you ever solve this issue? I have what I believe is the same problem: http://stackoverflow.com/questions/38792111/cant-verify-openssl-signature-in-c-sharp?noredirect=1#comment64959059_38792111 – lfalin Aug 05 '16 at 18:09

1 Answers1

2

The following code should do the trick for you. It loads the certificate from the file path given and then uses the public key to verify the data against the given signature. Returns true if valid.

            byte[] signature = Convert.FromBase64String(Signature);

            byte[] data = Encoding.UTF8.GetBytes(Data);

            var x509 = new X509Certificate2(Path.Combine(@"C:\test", @"test\test.crt"));

            var rsa = x509.PublicKey.Key as RSACryptoServiceProvider;
            if (rsa == null)
            {
                LogMessage("Authorize", "Invalid", Level.Alert);
                return false;
            }

            string sha1Oid = CryptoConfig.MapNameToOID("SHA1");

            //use the certificate to verify data against the signature
            bool sha1Valid = rsa.VerifyData(data, sha1Oid, signature);

            return sha1Valid;
Sharkz
  • 458
  • 1
  • 9
  • 25