none
How to verify an executable against a digital certificate

    Question

  • I have a .Net executable which I have digitally signed using a certificate generated through makecert.exe and signed using signtool. How to verify that exe has not been tampered or it is still using the certificate digitally signed by me.

    For ex - A situation where anyone can replace the exe which is digitally signed by another certificate and placed into Trusted Root Authorities.

    From various internet sources I read that the below code would just check if the certificate is valid

               X509Certificate signer = X509Certificate.CreateFromSignedFile(executablePath);
                X509Certificate2 certificate = new X509Certificate2(signer);
                var certificateChain = new X509Chain
                {
                    ChainPolicy = {
    
                        RevocationFlag = X509RevocationFlag.EntireChain,
                        RevocationMode = X509RevocationMode.Online,
                        UrlRetrievalTimeout = new TimeSpan(0, 1, 0),
                        VerificationFlags = X509VerificationFlags.NoFlag
                    }
                };
                var chainIsValid = certificateChain.Build(certificate);
                if (chainIsValid)
                {}

    And it is suggested to use WinVerifyTrust. My question is WinVerifyTrust would also validate the certificate, if the same exe is signed by another certificate deployed in Trusted Root Authorities. How can I associate the exe with my certificate? Or how the WinVerifyTrust can be helpful in this situation as mentioned everywhere? Please help!!

    Thanks

    Thursday, March 14, 2019 4:42 AM

Answers

  • You said "a certificate generated through makecert.exe" so I assumed it's self-signed certificate instead of CA ones.

    For self-signed variant both the name and serial number can be set arbitrarily, so you would need other means to verify the binary is signed with your own certificate.

    And yes, once a signed binary is tampered the "signature" is made invalid because the checksum will no longer be the same. That's the whole point of code signing: 1) verify the "signature" is valid, 2) verify the certificate is the one you are expecting - either a cert issued by trusted CA, or a cert you know exactly what it is.

    As additional information, since the certificate used in Microsoft/Windows Update is high-profile target by government to replace content with backdoor injected one, Microsoft employ the tactic I said - binaries to be installed from Microsoft Update are to be verified against a hardcoded certificate instead of just any trusted CA. This prevent the risk of government requesting CAs to issue certs in the name of Microsoft and use it to sign their trojans.

    • Marked as answer by Developer_111 Tuesday, April 9, 2019 10:59 AM
    Thursday, March 28, 2019 1:34 PM
    Answerer

All replies

  • > How to verify that exe has not been tampered or it is still using the certificate digitally signed by me.

    The question really is, who is going to do the checking?  You can put code in your application that takes a checksum of the file and verifies it against a known checksum that you've stored somewhere else.

    However:

    > For ex - A situation where anyone can replace the exe which is digitally signed by another
    > certificate and placed into Trusted Root Authorities.

    To solve that problem, you have to have some other entity to do the checking.  Clearly, if someone replaces the whole exe, then the code doing the checking is also gone.  This is similar to how driver checking works.  Each driver package has a catalog file that includes the certificate thumbprint and the checksum of each file in the package.  Before installing a driver, the operating system checks that all of the checksums still match.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Thursday, March 14, 2019 6:04 AM
  • If it's only self-signed cert., then IMO the only reliable way is to extract the public key from the signed binary(EXE or DLL) and then compare with your original one.

    Otherwise you have no way to tell if it's signed by yet another self-signed cert. that is trusted on that machine, generated with the same name with the same tuned datetime, and the same serial number and options. Only the salt used to generate the cert. keypair will show the difference.



    Thursday, March 14, 2019 6:22 AM
    Answerer
  • Hi

    Thank you for posting here.

    According to your description, you want to verify an executable against a digital certificate.

    Based on my research, you could try to use the SignTool to solve it.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, March 15, 2019 6:00 AM
  • Hi Tim,

    We are providing an option to the user to download a signed exe through a website. Using a separate background windows service, the downloaded exe is run at a specified intervals which is configured through a configuration file.  So here when the exe is run, we have to make sure it is the same singed exe. So I think this question - " Clearly, if someone replaces the whole exe, then the code doing the checking is also gone" is  not relevant here. 

    I have implemented a code something like this 

     private bool CompareCertificatesUsedForSinging()
            {
                bool isMatch = true;
                try
                {              
                   
                    X509Certificate signer = X509Certificate.CreateFromSignedFile(txtExecutablePath.Text);
                    X509Certificate2 execertificate = new X509Certificate2(signer);
                    var subject = execertificate.Subject;
                    var thumbprint = execertificate.Thumbprint;

                    var keyToBeVerified = subject + '|' + thumbprint;
                    if (keyToBeVerified != verificationKey) 
                    {
                        MessageBox.Show("Certificate Mismatch");
                        return false;
                    }
                    return true;         
                }
                catch (Exception ex )
                {
                    isMatch = false;
                }
                return isMatch;
            }

    verificationKey - is the combination of certificates Distinguished Name and Thumprint

    This checks if the certificates match in both the exe. The example you have given when tested using the code will show as mismatched certificates here. So will this be enough. I tried to tamper the exe manually, but I noticed that the signing goes off. Is there any unforeseen cases or will the code be enough to cover everythign?


    Friday, March 15, 2019 10:09 AM
  • Hi cheong00

    A certificate issued by a certificate authority will have  a unique serial number , but the serial number too would change once the certificate is renewed. So considering that case, I have used the combination - Certificates Distinguished Name + thumbprint which is considered to be unique worldwide as per few of the internet sources I have come across. Please watch the above thread for the code I have added. 

    I found that once an exe is tampered the signing goes off. So my question is will this function be sufficient enough to cover all the cases. You can refer the link https://stackoverflow.com/questions/24060009/checking-digital-signature-on-exe for a similar question.  It says "when the exe is tampered, the method doesn't detect. " According to my observation, once an exe is tampered, the signing automatically goes off. They have mentioend the use of WinVerifyTrust? What is the purpose of it? DOesnt my function cover all the cases.

    a) An unsigned exe 

    b) A signed exe but with different certificate

    c) A tampered exe

    d) A tampered exe but later signed with antoher certificate


    Friday, March 15, 2019 10:21 AM
  • Hi Jack,

    I want to implement this verification in C#.Net. Please go through the above thread for the solution I have implemented, though I am not sure if that is sufficient.

    Thanks

    Friday, March 15, 2019 10:24 AM
  • Hi

    Thanks for the feedback.

    The following link may be helpful for you.

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/5b69af77-29cd-4edb-9a09-38b91170c392/how-to-verify-microsoft-certificate?forum=csharpgeneral

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, March 27, 2019 7:56 AM
  • You said "a certificate generated through makecert.exe" so I assumed it's self-signed certificate instead of CA ones.

    For self-signed variant both the name and serial number can be set arbitrarily, so you would need other means to verify the binary is signed with your own certificate.

    And yes, once a signed binary is tampered the "signature" is made invalid because the checksum will no longer be the same. That's the whole point of code signing: 1) verify the "signature" is valid, 2) verify the certificate is the one you are expecting - either a cert issued by trusted CA, or a cert you know exactly what it is.

    As additional information, since the certificate used in Microsoft/Windows Update is high-profile target by government to replace content with backdoor injected one, Microsoft employ the tactic I said - binaries to be installed from Microsoft Update are to be verified against a hardcoded certificate instead of just any trusted CA. This prevent the risk of government requesting CAs to issue certs in the name of Microsoft and use it to sign their trojans.

    • Marked as answer by Developer_111 Tuesday, April 9, 2019 10:59 AM
    Thursday, March 28, 2019 1:34 PM
    Answerer
  • Hi cheong00,

    Sorry for the delayed reply.

    I was able to verify the certificates using these 2 strategies you have mentioned

    1) verify the "signature" is valid, 2) verify the certificate is the one you are expecting - either a cert issued by trusted CA, or a cert you know exactly what it is.

    Thanks

    Tuesday, April 9, 2019 10:59 AM