Get details on an EXE file signature with .NET - c#

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.

Related

Any way to grab digital signatures from a file using C#?

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.

Reading a digital signature from a file, c#, then verifying it

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

How to sign a ZIP file like I would sign an assembly?

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

C#: How to detect tampering of authenticode signed file

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

How to record a serial number in an executable?

I am trying to secure an application to only run from a specific USB disk.
I have code to get the serial number from the device, but the only way I can make this work the way I want to is to manually code the serial number into the binary.
Is there a way I could make a stub application that would modify the existing binary to insert the serial number into it after it's compiled?
I've seen this done in C++ in the past, but that was a long time ago and I cant quite remember how we did it back then.
Storing it in the assembly is a bad idea. Here is what I would do (and have done similar in the past):
Be sure you are signing your assemblies.
Create an XML document that contains your licensing data - in your case the serial number of the USB device.
Utilize the SignedXml library in .NET (implements XMLDSIG) to sign the licensing XML document that contains the serial number. You will use the same private key that is used to sign the assembly.
When your app starts up, it verifies that the signature of the XML file is valid using the public key that it was signed with (and is embedded in the assembly).
Obviously you don't ship your private key, so if the app needs to generate the XML config file itself (rather than it be a file you ship to the user) you will need to implement a web service.
I don't know, but that hasn't stopped me from answering before.
Maybe figure out where you want to store the SN in the executable (it should be only one place, right?) and just treat the executable as a giant binary blob, and use the stub program to insert it where it needs to go?
Perhaps you want to get a separate USB license key like these ones:
http://www.bhphotovideo.com/c/buy/USB-License-Keys/ci/12454/N/4294550039
???
Why would anybody want to save anything inside an executable. If you're planning to sign the executable for distribution changing the executable in some way would break the signing and saving something in binary to the executable won't prevent someone from taking the value out the executable.
Best thing you can do is store the serial number to a file, registry, or other place then encrypt the value so it can't be modified without breaking it. I use a library that ships with License Vault from a fairly new company called SpearmanTech. You can use their library to store encrypted values to the .NET machine.config file in an encrypted form so it can't be tampered with. This way you can pull the information from the .config file when your application starts.
Are you writing a .NET application in C++ or native C++ well either way you should be able to communicate with the .NET framework so this solution would work.
I would check out their product at http://www.spearmantech.com. Hope it works for you.

Categories