{"id":24897289,"url":"https://github.com/falk-werner/zipsign","last_synced_at":"2025-10-16T11:31:31.164Z","repository":{"id":37249818,"uuid":"222287149","full_name":"falk-werner/zipsign","owner":"falk-werner","description":"Sign and verify ZIP archives","archived":false,"fork":false,"pushed_at":"2025-08-27T18:31:42.000Z","size":308,"stargazers_count":40,"open_issues_count":0,"forks_count":14,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-28T03:24:20.200Z","etag":null,"topics":["cms","openssl","sign","signature","zip"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/falk-werner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-11-17T17:40:28.000Z","updated_at":"2025-08-27T18:31:45.000Z","dependencies_parsed_at":"2023-11-13T18:28:47.593Z","dependency_job_id":"69262550-a264-46ec-971f-909680a265a2","html_url":"https://github.com/falk-werner/zipsign","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/falk-werner/zipsign","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/falk-werner%2Fzipsign","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/falk-werner%2Fzipsign/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/falk-werner%2Fzipsign/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/falk-werner%2Fzipsign/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/falk-werner","download_url":"https://codeload.github.com/falk-werner/zipsign/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/falk-werner%2Fzipsign/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279183691,"owners_count":26121450,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-16T02:00:06.019Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","openssl","sign","signature","zip"],"created_at":"2025-02-01T20:17:17.834Z","updated_at":"2025-10-16T11:31:30.617Z","avatar_url":"https://github.com/falk-werner.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Ubuntu Build](https://github.com/falk-werner/zipsign/actions/workflows/build-ubuntu.yml/badge.svg)](https://github.com/falk-werner/zipsign/actions/workflows/build-ubuntu.yml)\n[![Windows Build](https://github.com/falk-werner/zipsign/actions/workflows/build-windows.yml/badge.svg)](https://github.com/falk-werner/zipsign/actions/workflows/build-windows.yml)\n[![Mac OS Build](https://github.com/falk-werner/zipsign/actions/workflows/build-maxos.yml/badge.svg)](https://github.com/falk-werner/zipsign/actions/workflows/build-maxos.yml)\n\n[![Snap Store](https://raw.githubusercontent.com/snapcore/snap-store-badges/master/EN/[EN]-snap-store-white.png)](https://snapcraft.io/zipsign)\n\n# zipsign\nSign and verify ZIP archives.\n\n## tl;dr\n\n-   create private key and certificate for signing  \n    `openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes`\n\n-   create a zip archive  \n    `echo 42 \u003e answer.txt`  \n    `zip -r archive.zip answer.txt`\n\n-   sign the archive  \n    `zipsign sign -f archive.zip -p key.pem -c cert.pem`\n\n-   verify signature of the archive  \n    `zipsign verify -f archive.zip -c cert.pem`\n\n## Command line options\n\n### Sign\n\nSign an archive.\n\n    zipsign sign -f \u003cfilename\u003e -p \u003cprivate-key\u003e -c \u003csigners certificate\u003e [-i \u003cintemerdiate\u003e ...]\n\n| Short | Long                | Argument    | Description                                              |\n| ----- | ------------------- | ----------- | -------------------------------------------------------- |\n| -f    | --file              | archive.zip | Required. ZIP file to sign.                              |\n| -p    | --private-key       | key.pem     | Required. Filename of signers private key.               |\n| -c    | --certificate       | cert.pem    | Required. Filename of signers certificate.               |\n| -i    | --intermediate      | inter.pem   | Optional. Filename of intermediate certifiacte to embed. |\n| -e    | --embed-certificate | _none_      | Optional. Embed signers certificate in signature.        |\n| -v    | --verbose           | _none_      | Optional. Enable additional output.                      |\n\nDuring signing the ZIP file will be altered (ZIP comment will be re-written).\n\nIt is possible to specifify none, one or more intermediate certificates, that will be embedded in\nthe signature. Embedding intermediate certificates are used to close then chain of trust for later\nverfication.\n\nIt is also possible to specify one or more signers by adding private key and certificate pairs.  \n_Note_: It is recommended to embed signers certificates when using multiple signers.\n\n### Verify\n\nVerfiy an archive.\n\n    zipsign verify -f \u003cfilename\u003e -c \u003csigners certificate\u003e [-k \u003ckeyring\u003e]\n\n| Short | Long          | Argument    | Description                                |\n| ----- | ------------- | ----------- | ------------------------------------------ |\n| -f    | --file        | archive.zip | Required. ZIP file to verify.              |\n| -c    | --certificate | cert.pem    | Required. Filename of signers certificate. |\n| -k    | --keyring     | keyring.pem | Optional. Filename of PKI.                 |\n| -v    | --verbose     | _none_      | Optional. Enable additional output.        |\n\nIf the archive is signed by multiple signers, multiple certificates can be\nspecified for validation.\n\n_Note_: Verfication is done only against the given certificates. Other signers are\nignored, even if the archive is signed by multiple signers.\n\n_Note_: Only one keyring can be specified.\n\n#### Return Codes\n\n| Return Code | Description |\n| ----------- | ----------- |\n| 0           | Verification succeeded |\n| 1           | General error |\n| 2           | Error - signature is missing |\n| 3           | Error - invalid certificate chain |\n| 4           | Error - invalid signature |\n\n### Info\n\nPrints signature of ZIP archive in human readable form.\n\n    zipsign info -f \u003cfilename\u003e\n\n| Short | Long          | Argument    | Description                                |\n| ----- | ------------- | ----------- | ------------------------------------------ |\n| -f    | --file        | archive.zip | Required. ZIP file to print info.          |\n\n\n## How it works\n\n[ZIP file format](https://en.wikipedia.org/wiki/Zip_(file_format)) specifies a comment field, \nwhich is located at the very end of the archive.\nThis allows to create a [CMS](https://en.wikipedia.org/wiki/Cryptographic_Message_Syntax) signature\nover the full archive (excluding the comment) and stores it Base64-encoded as new comment.\n\nFor verification, the comment is read from the archive and verified against archives contents.\n\n## Signature format\n\nZipSign used the following format for the signature\n\n    ZipSign=data:application/cms;base64,\u003csignature-data\u003e\n\nThe signature data consists of base64 encoded PEM data.\n\nTo print the signature from a previously signed ZIP archive, one can use the following command.\n\n    \u003e unzip -z archive.zip\n    Archive:   archive.zip\n    ZipSign=data:application/cms;base64,MIIDow...\n\n## Sign and verify using keyring (PKI)\n\nVerification using a PKI is supported via `--keyring` option during validation.  \nSetup a CA suitable for signing is a complex topic. A good starting point might\nbe the PKI tutorial at\n[https://pki-tutorial.readthedocs.io/en/latest/](https://pki-tutorial.readthedocs.io/en/latest/).\n\nThe test directory contains a bash script [create-pki.sh](test/openssl/create-pki.sh), which\ncreates a small PKI used within unit tests.\n\n    # sign archive alice key and certificate\n    zipsign sign -f archive.zip -p certs/alice.key -c certs/alice.crt\n\n    # verify archive using keyring\n    zipsign verify -f archive.zip -c certs/alice.crt -k keyring.pem\n\n## Include intermediate certificates\n\nTo complete chain of trust, on or more intermediate certificates can be specified.\n\n    # sign archive with alice's key and certificate, add signing CA as intermediate\n    zipsign sign -f archive.zip -p certs/alice.key -c certs/alice.crt -i ca/signing-ca.crt\n\n    # verify archive using root CA as keyring\n    zipsign verify -f archive.zip -c certs/alice.crt -k ca/root-ca.crt\n\n## Multiple signers\n\nAn archive can be signed by multiple signers.  \nThis might come in handy during certiface changes, e.g. when one certificate will expire\nshortly and the new one should be used simultaniously.\n\nTo sign an archive with multiple signers, you can specify one certificate and one private\nkey per signer. The certificates should be embedded in the archives signature, so they\ncan be located during verification.\n\n    zipsign sign -f archive.zip \\\n      -p certs/alice.key -c certs/alice.cert \\\n      -p self-signed/key.pem -c self-signed/cert.pem \\\n      -e\n\nDuring verification, you can choose the proper signer (or both).\n\n    # verify against self signed certificate\n    zipsign verfiy -f archive.zip -c self-signed/cert.pem\n\n    # verify against alice's certificates\n    zipsign verify -f archive.zip -c certs/alice.crt -k keyring.pem\n\n    # verify against both certificates\n    zipsign verify -f archive.zip \\\n      -c self-signed/cert.pem \\\n      -c certs/alice.crt -k keyring.pem\n\n## Known Limitations\n\n-   ZIP comments are limited to a maximum of 64 KBytes.  \n    CMS allows to include signer certificates, intermediate certificates as well as multiple signatures.\n    When overused, this might not fit into the comment.\n\n# Build\n\nTo build the project, cmake is used.\n\n    mkdir build\n    cd build\n    cmake ..\n    make\n    sudo make install\n\n## Build using Docker\n\nThere are some dockerfiles provided in [docker](docker) subdirectory.\n\n    docker build --rm --build-arg \"USER_ID=`id -u`\" --tag zipsign-ubuntu -f docker/ubuntu.dockerfile .\n\nTo run the docker container, use\n\n    docker run --rm --user=\"`id -u`\" -it zipsign-ubuntu\n\n## Build snap\n\nTo build the snap, install [snapcraft](https://snapcraft.io/docs/installing-snapcraft) and run the following command:\n\n```\nsnapcraft\n```\n\n## Dependencies\n\n-   [OpenSSL\u003e=3.0](https://www.openssl.org/) (libssl-dev)\n-   [Google Test](https://github.com/google/googletest) *(Test only)*\n\n## External references\n\n-   [ZIP file format](https://en.wikipedia.org/wiki/Zip_(file_format))\n-   [CMS](https://en.wikipedia.org/wiki/Cryptographic_Message_Syntax)\n-   [PKI tutorial](https://pki-tutorial.readthedocs.io/en/latest/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffalk-werner%2Fzipsign","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffalk-werner%2Fzipsign","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffalk-werner%2Fzipsign/lists"}