I'm trying to write a C# program that verifies the digital signature of exe's. The exe's are signed with an authenticode certificate, and I want to detect tampering.
I've been able to create a SignedCms instance as described here: Get timestamp from Authenticode Signed files in .NET
I assumed SignedCms.CheckSignature would do the trick, but this method never throws an exception... Even not when I modify some bits of the exe...
I'm assuming you've scoured the .NET Framework docs and didn't find what you needed. The answer to this StackOverflow question has a link that describes how to use the native Windows CryptQueryObject function to verify a signature. So all that's left is to check out PInvoke.NET to see how to bring that function into .NET.
Could you just shell to signtool.exe /verify, and check the result?
I recently wrote a simple app which signs executables using the same method, and it works great.
Signtool on MSDN
Related
What I'm looking to obtain is a list of signatures on a given file that's been digitally signed ( code signing certificate ) - When you use signtool to sign with a sha1 certificate, you can also sign with a sha256 certificate for instance- Both of these signatures can be found in the file properties under Digital Signatures, under a signature list - You can also see a timestamp if you used that as well.
Is there a standard way to grab that list/details or is this diving into p/invoke territory?
var cert = X509Certificate.CreateFromSignedFile(fileName);
This almost gets me what I need, it assures me a file has a signature and can even build a certificate out of it, it seems - I can then grab the common name and such and do some basic checks from there.
I don't, however, get both signatures, and can't seem to find a way to do so.
Would prefer to do this using standard .NET if possible, but understand that may not be possible. Thanks in advance!
Got an answer for using in console, could likely adapt it for windows forms easily enough but something usable for windows forms out of the box would be great.
I have an executable that I would like to protect from changes to the File Version Info.
I initially thought that signing the exe with a certificate would handle this, however when you modify the File Version Info with freely available utilities, it seems that the digital signature still remains intact.
I figure the only way would be to perform some sort of checksum on the exe, however this isn't ideal as I'm concerned that this will cause problems with various post-processors (obfuscation, anti-debug, etc) that I am doing which deny access to the .exe at run-time.
Is there any other way I detect if the File Version Info has been modified in some way?
The certificate is not more valid if only 1 byte of the executable changed.
It seems you use Properties window of Windows Explorer and after changing the version number see the Digital Signature tab still there. This is very misleading about digital signature of executable files in Windows but not true.
This tab just say the file contain certificate but nothing about validation of this certificate. In this tab click on certificate and then click on Details, now on top of the opened window you can see the cert is valid or not.
By using Windows API you can check the certificate is valid or not, maybe this topic help you in C#.
I've been looking around, and see that visual studio c++ has some "native" tools to remove a digital signatures.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680214(v=vs.85).aspx
Of course I am doing this with documents, specifically for pdf files so I don't know how that function would work since it seems intended for images.
If it can remove it, could it also read it and return the signature? Right now I am using c# and wanted to have the program actually capture the digital signature so it can be verified, but one step at a time. Everything I read about System.Security.Cryptography.X509Certificates seems to indicate that it can only do any of its functions once the files are assigned X509Certificates related classes.
I've also never imported c++ code into c#, but I know it is possible.
http://social.msdn.microsoft.com/Forums/en-US/f18d1d1c-0d14-4ff2-8244-337f58818ef9/how-to-use-c-code-in-c?forum=vssmartdevicesvbcs
I'm trying to retrieve the details on an executable file's digital signature in a managed code. I basically need the name and the issuer off the cert. There's a C++ code sample from Microsoft that explains it for C++, but is there a similar way of doing it with C#?
Create a crypto object from the signed file, using this function :
http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate.createfromsignedfile%28v=vs.100%29.aspx
Then call the .Issuer property on that object.
I have a ZIPfile containing signed .Net assemblies, is it possible through a tool to sign not code but a ZIPfile containing those too? I'd like to be able to work with this on the code side saying something like:
if(myzipfile.IsSignedBy(name))
{
DezipFile();
LoadAssemblies();
}
Another standardized way to sign an arbitrary number of file of any format is to use a seperate Catalog file (.cat). This is commonly used to sign drivers but also used in some Microsoft published ISOs.
What You Get
How to Create
For this you need Powershell, and a file (or a directory of files) to sign.
Supposed that the file you want to sign is called AZipFile.zip. Run the following
New-FileCatalog -Path AZipFile.zip -CatalogFilePath myCatalog.cat -CatalogVersion 2.0
This will create a catelog file but without a signature. Image
Run the following to add a signature. A timestamping server is required so that the signature is still valid after the signing certificate expires. Replace Cert:\CurrentUser\My\18daf8ffb3dc9d84903a9eb65fb8a1970ceb7139 with the path to your certificate
Set-AuthenticodeSignature -FilePath myCatalog.cat -Certificate (Get-Item Cert:\CurrentUser\My\18daf8ffb3dc9d84903a9eb65fb8a1970ceb7139) -TimestampServer http://timestamp.comodoca.com
Now the catalog file shows a valid signature. Image
How to Verify
By double clicking on the catalog file on windows, you are able to see if the signature is valid, and a list of files and their hashes. However, the GUI does not help you verify the files. For this you need another powershell command.
Test-FileCatalog -CatalogFilePath myCatalog.cat -Path AZipFile.zip
If the signature to all files under the catalog is valid, it returns Valid.
You can sign anything you like, the only issue you'd have to worry about is where you're going to store the signature to verify it.
In C# you have an RSACryptoServiceProvider which can take a keypair and a byte[] and produce an RSA signature of it. To verify it you just need the public key (not the private one), the original data and the generated signature.
With a bit of cleverness you could perhaps append the signature to the end of the ZIP file without rendering the ZIP file unreadable. You'd then read the entire zip file (minus the part at the end where you store the signature) and verify using that.
You'd have to embed the public key inside your application in order to use it for verification as well.
Since only you have both the public and private key used to make the signature, then you can be sure that if the signature is correct that the zip file came from you.
IF you don't have to use ZIP for compression, another format might be a better alternative. This stackoverflow thread mentions that JAR files support signing.
Seems like ZIPs themselves do not have widely-used standards for signatures, but there're several ZIP-based formats which define digital signatures. The most .NET-related of them must be Open Packaging Conventions (the container format for Word/Excel documents or Visual Studio extensions), digital signatures described here: https://msdn.microsoft.com/en-us/library/windows/desktop/dd742818(v=vs.85).aspx#digital_signatures