X509Certificate2.Verify behaviour - c#

I have a digitally signed binary app.exe. Certificate is issued by commercial CA. In file properties (on Windows), Digital Signature information says that This digital signature is OK. If I somehow modify binary (e.g. by changing resources in Resource Hacker) Digital Signature information says that This digital signature is not valid.
I tried to verify certificate programmatically but X509Certificate2.Verify() returns true no matter which file I use - original (app.exe) or tampered one (app-modified.exe).
string filename = "app.exe"; // "app-modified.exe"
X509Certificate cert1 = X509Certificate.CreateFromSignedFile(filename);
X509Certificate2 cert2 = new X509Certificate2(cert1);
bool isValid = cert2.Verify();
Why does this function return true in both cases? Is this a proper way of validating digital signatures of files?

I think that you are misunderstanding the digital-signature verification process. Roughly verify digital-signature process consists in two steps, first step is validate the signature integrity (check that no one modify the document after signature is applied), and the second step is validate certificate status (check that certificate is valid, not expired or revoked).
So If you modify your signed app.exe you are broken your signature, but if the certificate was valid it remains valid which is the reason that in both cases your certificate validation is ok.
If instead of validate only the certificate you validate the signature the result will be false in the app-modified.exe because when you modify the app.exe you broke the signature.
Hope this helps,

Related

Using coSign, can not figure out how to use .cer/.pfx files to sign and verify pdf documents in c#

I was recommended coSign for c# to sign and verify documents. I can't find anything helpful on the subject of using .cer and .pfx files to sign pdf files. I was assuming it would be as easy as loading a .cer file as a X509Certificate2, and then coSign could just import it.
Samples for coSign seem limited. I was able to get coSign to verify if a document had a signature already on it, but I have no idea if it can verify if that is the same one based on the digital certificate.
I've also used another library to sign documents with those type of certificate files. It is not able to verify digital signatures though.
With CoSign you can import externally-issued certificates and keys to your CoSign account. However, it is important to note that typically every CoSign account (whether CoSign on-premise or CoSign Cloud) by default already includes a key and a certificate that can be used for signing.
If you do want to use a different signature key and certificate issued on a PFX file, for example, you can follow the procedure below:
From a command-line run the utility C:\Program Files\ARX\ARX CryptoKit\utils\pkcs12util.exe
You will need to specify the PFX filename and PFX file password
Your CoSign account should now include the key and certificate from the PFX file and you can use CoSign SAPI for signing with it.
When you create a CoSign Trial or Cloud account the certificate is created on the CoSign Appliance for you. You cannot import your own certificate to the appliance, nor do you need to.
The API calls should be made to the CoSign appliance in order to function, at no time can signatures be made if the CoSign appliance is not being used (otherwise it wouldn't be so secure). You will notice that even with your CoSign user certificate that you cannot export a PFX or P12 file, because you can never export the private key from the appliance.
Regards,
Dave Strang
The Digital Signature Company
Phone: (866) 327-9754
Email: daves#arx.com
Website: www.arx.com

Given two X509Certificate how to tell if one is signed by the other

I have two serialized certificates in the DB from which I can construct the X509Certificate. How to tell if one certificate is signed by the other. I don't want to check based on the IssuerName as it is not reliable(for my scenario).
IssuerName property and Authority Key Identifier extension are the way to find relationships between certificates. Once you match them, you can verify if the supposedly parent certificate is actually the CA certificate of the one being checked. I am not sure that such checks are possible with .NET Framework alone, and our SecureBlackbox does this easily, with one method.

Validate if certificate is revoked

I have the following situation:
Java Applet for digital signature - on client side
Validation of digital signature and digital certificate - on server side
I'm using the following C# code to validate the signature and the certificate:
ContentInfo content = new ContentInfo(pdf);
SignedCms signedMessage = new SignedCms(content, true);
signedMessage.Decode(assinatura);
signedMessage.CheckSignature(false);
Where:
pdf - signed pdf file
assinatura - pdf's signature - in my case, the signature it's not with the pdf file
By the tests I made, the code validate the certificate chain, the expiration and others...
However, I would like to know a few things:
This code validates that the certificate used for signing is revoked? If it does not validate, how could I make such a validation system at this point?
Is there a way to create a certificate that is revoked for testing?
Revocation check is performed by
Obtaining CRL that can contain information about the status of the certificate
Sending OCSP request to the server authorized to respond to such requests
If OCSP server's URL is present, OCSP is the preferred (for security) method to check revocation, but in general both checks should be performed.
OCSP and CRL operations are supported by our SecureBlackbox, CryptLib, BouncyCastle. In SecureBlackbox you will find a high-level CertificateValidator class which does all checks for you (at the same time letting you interfere in all aspects of the procedure).
There's no way to create a revoked certificate unless you run your own private certificate authority (but if you did, probably there would be no question). The reason is that you can't put your certificate's ID to the CRL sent by CA (or make the third-party OCSP responder do this).
Oh, I can see one way - buy a certificate, then contact the CA and tell them that you've disclosed the private key. They will block the certificate. But this is quite costly method :).

Read certificate from pdf

I'm using ITextSharp in order to read certificate informations from digitally signed pdf document.
The ITextSharp.Text.Pdf.PdfPKCS7 class exposes three properties:
Certificates (as list)
SignCertificate (as single object)
SignCertificateChain (as list)
How can I combine these three properties in order to achieve all info about a single certificate?
I'd be able to show all certificate path (all nested certificates).
Certificates gives you the list in no particular order, including certificates that weren't used for the main signature.
SignCertificate gives you the certificate of the actual signer.
SignCertificateChain gives you the list where the first Certificate is the SignCertificate, the next is the certificate of the instance that issued the SignCertificate, the next is the certificate of the instance that issued the previous certificate, and so on. This can return less certificates than Certificates, because only the certificates used for the main signature will be returned.
So you don't need to 'combine' the properties to show the certificate path, you just need SignCertificateChain. Note that your question isn't entirely clear:
'all info about a single certificate'
kind of contradicts with
'show all certificate path (all nested certificates)'
If you want to visualize the chain that resulted into the signing certificate, you need to look at more than a single certificate (unless the certificate was self-signed in which case there's only one element in the chain).

Can I verify an XMLDSIG signature in .NET without requiring the root certificate be installed?

I'd like to use XMLDSIG for verifying that a .config file has not been tampered with. I also want to be able to verify the signature chain so that I can trust the signature.
I've got three certificates in the chain:
Root CA -> Intermediate Signing CA -> Signing Key
I check that the file is signed with a key that is issued by the intermediate CA.
I'd like to do this without installing any certificates in the user's Windows certificate store. These are self-signed certificates, so not every user is going to want me installing them in their Root store. I don't have a problem with installing them in my root store.
I have the original .CER files -- they're included in the Signature block, and I can include them with the verification code. I can build a certificate chain from this by using X509ChainPolicy.ExtraStore.
If the certificates are not installed in the root store, and I verify the chain, then X509Chain.Build returns false, and the chain has a X509ChainStatusFlags.UntrustedRoot in it.
Can I add trusted certificates just for the duration of this operation?
Assuming you have physical copies of the public keys of ALL signing certs in the trust chain, then this is possible by using the OpenSSL command line tool.
http://www.madboa.com/geek/openssl/#verify-standard
It's a bit of a steep learning curve at first, but a very powerful utility.
If you don't have the signing certs, then you cannot verify anything. That would be the same as trying to verify a human signature without having seen the original. You have nothing to compare to, so how could you verify the authenticity?
Update
There's something here perhaps that could help you:
http://social.msdn.microsoft.com/Forums/eu/clr/thread/1966a6e8-b6f4-44d1-9102-ec3a26426789

Categories

Resources