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

14,134

Solution 1

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.

Solution 2

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

enter image description here

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.

Solution 3

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

Solution 4

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.

Share:
14,134
Ronan Thibaudau
Author by

Ronan Thibaudau

Updated on June 04, 2022

Comments

  • Ronan Thibaudau
    Ronan Thibaudau almost 2 years

    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();
    }
    
  • Ronan Thibaudau
    Ronan Thibaudau almost 11 years
    I don't want to embed the signature, that's not signing (i don't care if the zip file is unreadable, it could be zip or anything else, i don't need for the format to "support it", i want to take a file "bla", sign it (it's fine if nothing can read it) with the same signature i use to sign assemblies (a pfx file) be able to validate it and end up with the original unsigned file. (i'm making a plugin system, i want to display "plugin X made by X corporation" on the plugin activation menu in my application and a plugin is multiple dll+other files, i want to be sure nothing is tampered)
  • Ronan Thibaudau
    Ronan Thibaudau almost 11 years
    Any file foramt that allows me to have multiple files and can be read (natively or with a pure .net plugin, paid or free) is an option. Can i sign those with the same signature i use to sign code? (pfx file)?
  • PhonicUK
    PhonicUK almost 11 years
    Then just do what I said and keep the signature in a different file. You can use a X509Certificate2 object to read your pfx file and extract the PPKs for use with RSACryptoServiceProvider and then use RSACryptoServiceProvider.SignHash to generate the signature. Embedding the sig is still signing (your signed executable has its signature embedded afterall) but if you want it to work for any file then it is indeed best to keep the sig in a separate file.
  • Ronan Thibaudau
    Ronan Thibaudau almost 11 years
    I'm confused about how this works then, i thought when you signed an exe, the signature was embeded but the whole executable was modified no? Else how can you confirm the file wasn't tampered? (someone could change the file and copy/paste the signature if you only append it).
  • PhonicUK
    PhonicUK almost 11 years
    Because when you tried to validate the signature it wouldn't match - since it must be one created with your original public key in order to work. The signature is a cryptographic hash of the entire file.
  • Ronan Thibaudau
    Ronan Thibaudau almost 11 years
    I see i was confused, so this solution would work on any file format then. Is there a tool i can use to sign the file or do i need to do it by hand? I know for code i can use a tool but i don't know if i can have it working automagically like that?
  • PhonicUK
    PhonicUK almost 11 years
    No tool that I know of, but the C# code to do it is pretty trivial.
  • Ronan Thibaudau
    Ronan Thibaudau almost 11 years
    Could you give me a sample? I never worked with signing out of giving the path in visual studio and letting it sign my assemblies, so quite clueless as how to do this from code, all i have is a pfx file (from an authority that is available to both me and my clients) and a password to sign it with as well as an original unsigned file, and i have no idea where to start with.
  • Ronan Thibaudau
    Ronan Thibaudau almost 11 years
    I don't really get it, i mean i get the point, pass the data and the hash algo but, what do i do with my pfx key then? What is the algo i'm supposed to use if i want the same thing as signing it with a key? If i'm just hashing it instead of signing it, people can temper with the file and recompute the hash. Do you have a sample that takes pfx file + pwd + file as input and gives signed file as output?
  • PhonicUK
    PhonicUK almost 11 years
  • EricLaw
    EricLaw about 9 years
    JAR Files are ZIP files with certain additional conventions applied. There are tools that sign JAR files already.
  • Donal Fellows
    Donal Fellows over 5 years
    Link is semi-dead. It resolves and loads, but none of the critical images on the page do and the content isn't fully comprehensible without it.
  • n0rd
    n0rd about 5 years
    As of about a year ago one can (ab)use Nuget package signing for that. Technical details.
  • Ronan Thibaudau
    Ronan Thibaudau almost 5 years
    The goal is to be able to validate the signature from .net, everything you displayed is command line and GUI viewable, i'm upvoting this but unless there is a way to create .cab, sign them and verify them from .net the current accepted answer is a better fit
  • fjch1997
    fjch1997 almost 5 years
    @RonanThibaudau Good point, I didn't realize that the question wanted .NET code. But here is a one-liner for you PowerShell.Create().AddScript("New-FileCatalog -Path AZipFile.zip -CatalogFilePath myCatalog.cat -CatalogVersion 2.0").Invoke. The return value (object) can be examined by using dynamic.
  • fjch1997
    fjch1997 almost 5 years
    no .cab file is necessary. No need to put the files into any kind of format. It is just generating a .cab that contains signatures.
  • fjch1997
    fjch1997 almost 5 years
    I agreed that the current answer is the best way if all that's needed is programmatic access