user2771273
user2771273

Reputation: 1

Can't validate signature value using certificate public key provided in an xml (X509Certificate2)

I spent 100s of hours researching this subject, and other senior programmer who coded the original project also could not make it work. I have an xml with a parameter of SignatureValue, Certificate (X509Certificate2) and Digest Value. The created and given Signature value stated in the same xml was made by converting concatinated fields (equal to Digest Value) into a hash (SHA1), then encrypted via private key. Private key is taken out of the certificate for privacy and I only have the Public key within. Now, no matter how I code around it, I always get a false value back (as in VerifyHash/verifyHashResult is false). Here is the code I am using:

// Need your help please.

 static void VerifyHash(string sigVal , string digestVal, System.Security.Cryptography.X509Certificates.X509Certificate2 cert)
        {
            sigValInBytes = Convert.FromBase64String(sigVal);
            try
            {
 using (RSACryptoServiceProvider rsaProviderDecrypt = (RSACryptoServiceProvider)cert.PublicKey.Key)
               {
// Line below always return value of FALSE no matter how I code it. Here I want to verify the hashed freshly calculated digest value that is now hashed with the signature value
                    rsaProviderDecrypt.Decrypt(sigValInBytes, false);

                   rsaProviderDecrypt.Dispose();
               }
             }
        }


// At the main program I get the certificate from the xml given and call the method above:

main
{
// Code below gets the certificate details from a given xml, details of each variable confirmed to be accurate.
char[] Base64_x509ByteArray;
Base64_x509ByteArray = t.DigitalSignatures.First().X509Data.ToCharArray();
byte[] x509ByteArray;
x509ByteArray = Convert.FromBase64CharArray(Base64_x509ByteArray, 0, Base64_x509ByteArray.Length);

// Here am creating the certificate from the gathered data/certificate:
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(x509ByteArray);

VerifyHash(t.DigitalSignatures.FirstOrDefault().SignatureValue.Trim(), concatenatedFieldValues, cert);

}

Upvotes: 0

Views: 2366

Answers (1)

Guest
Guest

Reputation: 126

Some shots in the dark:

  1. Find the piece that is broken: Try doing the entire "encrypt / hash check" process in code without transfering anything over XML. If you can hash a string locally, and the hashes match, then the problem is in XML. Otherwise, the problem is in the cert or decryptor.

  2. If the problem is on the cert / encryptor side, try hash matching with a local .NET cryptography class. If that fails, the problem is an encryption setting. Otherwise, it is the cert.

  3. BIG shot in the dark: The call to Dispose right after the hash check. It shouldn't matter, but that caused an issue while I was decrypting using the Rijndael algorithm. Best guess was the optimizer was closing the stream early or something weird like that. Moving the constructor out of the using statement and manually calling Dispose after accessing the result fixed that "optimization".

  4. Might try a reversable encryption algorithm. Rinjdael is native to .NET, and is reversable. Good for debug and proof of concept work. (Note: it uses Time as part of the salt, so RJ doesn't match hashes, it decrypts. So not good for passwords in Production environments.)

  5. If the XML is the cause, check the encodings. Encryption is very sensitive to encodings, and XML serializers are finnicky beasts to begin with. The strings may look the same, but represented differently, or extra control characters added. Sql Server nvarchars are UCS-2, varchars are iso-8859-1, C# strings are utf-8, etc. Easy for encodings to mis-match, and an encoding change would easily cause this. Try converting the original value to utf-16 before inserting into the Xml, and set the Xml Declaration Encoding to utf-16. Just to be safe.

  6. Note about NotePad: if you have opened the Xml in Notepad to take a quick look or edit, and saved it, there are probably extra "end of line" characters on your strings now. If you did the same in Word... oh my... Might want to try an original copy.

  7. Failing that, try generating new encrypted values and see if they match.

Upvotes: 1

Related Questions