tags:

views:

156

answers:

1

I have:

  1. x509 certificate (Base64);
  2. String data;
  3. Signature of string data (Base64).

Is it possible to check signature?

My code:

  bool valid = false;

  var signature = Convert.FromBase64String(base64Signature);
  var data = Encoding.UTF8.GetBytes(stringData);

  var x509 = new X509Certificate2(Convert.FromBase64String(certificate));
  var dsa = x509.PublicKey.Key as DSACryptoServiceProvider;
  if (dsa!=null)
    valid = dsa.VerifySignature(data, signature);
  else {
    var rsa = x509.PublicKey.Key as RSACryptoServiceProvider;
    if (rsa!=null)
      valid = rsa.VerifyHash(data, ???, signature);
  }

I don't know what I should use instead of ???. It is possible to get hash algorithm from certificate?

+1  A: 

The sender of the original message may use whatever algorithm he likes to sign his message, using the private key that corresponds to the certificate. While you can get the OID of the algorithm used to sign the certificate from its the SignatureAlgorithm property, nothing prevents the sender to use a different signing or hashing algorithm.

According to the documentation, the only valid hashing algorithms for the RSA provider are SHA1 and MD5. Perhaps you should try VerifyHash with both algorithms and check which one succeeds. You can get the proper OID for each one using the CryptoConfig.MapNameToOID method like this:

string sha1Oid = CryptoConfig.MapNameToOID("SHA1");
string md5Oid = CryptoConfig.MapNameToOID("MD5");
bool sha1Valid = rsa.VerifyHash(data, sha1Oid, signature);
bool md5Valid = rsa.VerifyHash(data, md5Oid, signature);
valid = sha1Valid || md5Valid;
Panagiotis Kanavos
I guess you meant `CryptoConfig.MapNameToOID("MD5");` for the second line.
Bruno
Thanks. Some remark: I must use VerifyData.
Unholy