Programmatically checking the Authenticode signature on a file



While I was at MEDC 2006, someone asked me if there was a way to find out programatically what certificate a file is signed with. The answer is yes, and it is really easy using the cryptography libraries on the .Net Framework. (This is desktop code).


Don’t forget to add a reference to the cryptography libraries and then the following using statements to your file:



using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;


The following function will return you an X509Certificate object that you can later use to get additional information, like the certificate issuer. For more information on the X509Certificate class, take a look at http://msdn2.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate_members.aspx .


/// <summary>
///
Gets the certificate the file is signed with.
///
</summary>
/// <param name=”filename”>The path of the signed file from which to
///
create the X.509 certificate. </param>
/// <returns>The certificate the file is signed with
</returns>
public X509Certificate GetAppCertificate(string
filename)
{
   
X509Certificate cert = null
;
   
try
    
{
      
cert
= X509Certificate.CreateFromSignedFile(filename);
   
}
   
catch (CryptographicException e)
   
{
       
Console.WriteLine(“Error {0} : {1}”, e.GetType(), e.Message);
       
Console.WriteLine(“Couldn’t parse the certificate.” + 
                          “Be sure it is a X.509 certificate”
);
    
}
    return cert;
}


Enjoy!


Luis E. Cabrera
Windows Mobile Team.
====
This posting is “AS IS” and confers no rights or privileges.


Comments (16)

  1. scyost says:

    You can also do it from the command line using PowerShell – http://blogs.msdn.com/windowsmobile/archive/2006/03/02/monad_signature_checking.aspx

  2. native says:

    Any way to do this with native C++ to ensure a file is signed with the correct signature? i.e. check the DLLs an application depends on are signed by the original provider (possibly myself)

  3. I think the title of this entry is a bit misleading. The code only extracts the signature. It doesn’t in any sense ‘check’ that the signature is correct.

    If the file has been tampered with, this code won’t notice.

    I built and signed an MSI file. This code was able to extract the signature just fine. I then modified the MSI file by one byte without resigning it. I verified that the signature was invalid by trying to download and install the MSI from a web server using Internet Explorer. This always checks the signature, and it correctly detected the problem when I had tampered with the file. (It was happy with the original unmodified signed file.)

    But when I opened that same modified file with your code here, it just returned the certificate as before, without reporting an error.

  4. LuisCa says:

    Ian,

    You are right. The code is not meant to verify that the signature is correct.

    The code is meant to help you just check what certificate the file was signed with. That was what the person at MEDC asked for.

    Thanks,

    -Luis.

  5. NS says:

    CryptVerifyMessageSignature is not supported in windows mobile. Then how to get PCCERT_CONTEXT from WIN_CERTIFICATE?

  6. Kris says:

    One I get the certificate how can I Programmatically verify the Authenticode signature?

  7. Jeff says:

    I am really concerned about this issue.

    I have code that does exactly what is being requested in the earlier replies:  I verify that the Authenticode signature is not only present, but valid as well.

    My current implementation uses the CAPICOM library – which appears to be the only way to test an Authenticode signature.

    Unfortunately, Microsoft lists CAPICOM as "not supported" on Windows Vista.  They recommend using .Net instead… but I can’t find any way to do this from .Net.  Everywhere I look, people recommend using CAPICOM!

  8. Moi says:

    Checkout WinVerifyTrust in the Platform SDK.

  9. Maen says:

    i want to know Programmatically how to know if a dll has

    digital signature tab  

    (right click –>properties–>digital signature)

  10. Maen says:

    i tried FileVersionInfo but there is no info about digital signature

  11. MaEn says:

    i want to know if its signd

    and if it was signed i want to know the

    "signer name " and the "time stamp"

    the "cert " has alot of data

    in it but i cant find

    "signer name " and the "time stamp"

  12. MaEn says:

    plz help as soon as possible

    Thanks

  13. alphatop says:

    this function is not supported on Windows Mobile OS, any method instead?

  14. Christophe Aubert says:

    Hi,

    As far as I understood, on the X509Certificate class,

    you can retrieve the name of the Certificate authority who

    delivered the Certificate using the Issuer property.

    The name of the person who provided the sign

    assembly (or msi in your example) can be retrieved

    with the Subject property.

    Concerning the validity period, it starts on

    GetEffectiveDateString() and ends on

    GetExpirationDateString().

    But this doesn’t help on how to check the validity of

    a file signature…

    Regards

  15. alphatop says:

    Thanks for the reply. So if I want to find out what certificate a file with programatically, the only way is using the X509Certificate class right? It seems that there is no other method if I want to implement this function by using Win32 API.