Signing .deb packages

Okay, so here’s the scenario: you distribute .deb packages without an apt repository, but want to start signing your packages to ensure they aren’t corrupted or tampered with during transit to your users. I say “without an apt repository” since apt has its own mechanism for signing whole releases, via SecureApt.

The tools you are expected to use for this purpose are debsign and debsign-verify. Unfortunately I found the documentation for these to be pretty thin and ended up having to read the source of debsig-verify to work out what was expected of a signed package.

So hopefully to prevent others from having to trawl through source code, below are steps you could follow to sign your own .deb packages. My method is somewhat contra to the prescribed method from Debian, however it is the only way I’ve managed to get working.  Please suggest better methods if you know them.

The steps I performed were:

  1. Create your GPG signing key, run

    $ gpg --gen-key


    and follow the steps.

  2. Sign the .deb with your private key, without using debsign (please comment if you get debsign to work for you, I couldn’t…).
    1. Take an existing .deb and unpack it:

      $ ar x my_package_1_0_0.deb

    2. Concatenate its contents (the order is important), and output to a temp file:

      $ cat debian-binary control.tar.gz data.tar.gz > /tmp/combined-contents

    3. Create a GPG signature of the concatenated file, calling it _gpgorigin:

      $ gpg -abs -o _gpgorigin /tmp/combined-contents

    4. Finally, bundle the .deb up again, including the signature file:

      $ ar rc my_package_1_0_0.deb _gpgorigin debian-binary control.tar.gz data.tar.gz

  3. Export your signing public key and determine its key id.
    1. Export your public key:

      $ gpg --export -a > my-debsig.asc

    2. Extract the key id by taking the last 4 chunks of the fingerprint, CA58BC6A0695623E in this case. We always use it without the spaces:

      $ gpg --fingerprint
      /home/floyd/.gnupg/pubring.gpg
      ------------------------------
      pub   1024D/0695623E 2009-02-04
            Key fingerprint = 6577 AAB2 8850 9E0B 1059  C510 CA58 BC6A 0695 623E
      uid                  Purple (Floyd) <--your email address-->
      sub   2048g/EB122979 2009-02-04

  4. Setup the machine(s) that will be downloading and verifying the package.
    1. Install the debsig-verify package

      $ apt-get install debsig-verify

    2. Import the public key into the debsig keyring:

      $ mkdir /usr/share/debsig/keyrings/[key_id]
      $ gpg --no-default-keyring --keyring /usr/share/debsig/keyrings/[key_id]/debsig.gpg \
            --import my-debsig.asc

    3. Configure a policy for the key, policies are discussed in some detail in /usr/share/doc/debsig-verify. The policy file needs to be kept in /etc/debsig/policies/[key_id]/[policy_name].pol. Mine looks like this:

      <?xml version="1.0"?>
      <!DOCTYPE Policy SYSTEM "http://www.debian.org/debsig/1.0/policy.dtd">
      <Policy xmlns="http://www.debian.org/debsig/1.0/">
      
        <Origin Name="PurpleFloyd" id="CA58BC6A0695623E"
                Description="Another package from PurpleFloyd"/>
      
        <Selection>
          <Required Type="origin" File="debsig.gpg" id="CA58BC6A0695623E"/>
        </Selection>
      
        <Verification MinOptional="0">
          <Required Type="origin" File="debsig.gpg" id="CA58BC6A0695623E"/>
        </Verification>
      
      </Policy>

  5. You should now be able to verify the package using debsig-verify, i.e.:

    $ debsig-verify my_package_1_0_0.deb
    debsig: Verified package from `PurpleFloyd' (Another package from PurpleFloyd)

Et voila! You have signed and verified a debian package.

Note: on most distros, dpkg/apt will not check the signature of a package when installing it, even if a signature is present. This checking can be enabled by removing the --no-debsig line from /etc/dpkg/dpkg.cfg.

2 comments so far

  1. copello on

    debsigs actually works, you just need to specify the type of signature For example:

    debsigs –sign=origin test.deb

    will sign the debian package. The problem here is that on Ubuntu, dpkg and gdebi uses different ar format. A deb package signed by debsigs will not work with gdebi because of this bug. It will install via dpkg.


Leave a reply