How to sign rpms with GPG

Updated -

RPM package signatures can be used to implement cryptographic integrity checks for RPM packages. This approach is end-to-end in the sense that the package build infrastructure at the vendor can use an offline or half-online private key (such as one stored in hardware security module), and the final system which consumes these packages can directly verify the signatures because they are built into the .rpm package files. Intermediates such as proxies and caches (which are sometimes used to separate production servers from the Internet) cannot tamper with these signatures.

The following steps describes the process of generating a GPG key and signing RPMs with the key.

  • First generate a gpg key pair on the machine.

    [root@localhost ~]# gpg --gen-key
    GnuPG needs to construct a user ID to identify your key.
    ...
    Real name: Package Manager
    Email address: pmanager@example.com
    Comment: RPM Signing Key
    You selected this USER-ID:
        "Package Manager (RPM Signing Key) <pmanager@example.com>"
    ...
    gpg: checking the trustdb
    gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
    gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
    pub   2048R/B74246CE 2017-03-22
          Key fingerprint = BCE7 1F72 7D86 E857 2B3F  1790 7255 CF3E B742 46CE
    uid                  Package Manager (RPM Signing Key) <pmanager@example.com>
    sub   2048R/D8FA7BFF 2017-03-22
    
  • Confirm and see the generated key.

    [root@localhost ~]# gpg --list-keys
    /root/.gnupg/pubring.gpg
    ------------------------
    pub   2048R/B74246CE 2017-03-22
    uid                  Package Manager (RPM Signing Key) <pmanager@example.com>
    sub   2048R/D8FA7BFF 2017-03-22
    
  • Export the Public key.

    [root@localhost ~]# gpg --export -a 'Package Manager' > RPM-GPG-KEY-pmanager
    [root@localhost ~]# cat RPM-GPG-KEY-pmanager
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: GnuPG v2.0.22 (GNU/Linux)
    
    mQENBFjSgckBCADob86RSLTExhr8T/P69vz4MjE2EDHUmCN+tFYUaDgmkpZBpU40
    Qs6WdOuBUvXevPQfKCj1OaRTouzGGGsvv7W/hHIKZ1IdY5HOXHbHZdkcghnaAGTj
    VdctgkXyLj+qMI9mvRAMaHiiTbD8AoPsT/uGMeg94R3FhO5hgXDQc5xADhvXU3+8
    MzeBmaYxAYRZ65Vc/8XgAPMDK+kIZZ0VQMB0Gzxio2OCMTy7uNg9QOqkYhPuVYh8
    GarrP6bZNzeImT8k615/+9rYo9Ys0mY4tq0N4RlZCjhJ/PIMoRjhEgtGe643DXUh
    EMpk477niWvolaE3PxZjFXRGxQN/VjjWoy9vABEBAAG0OFB1c2hwZW5kcmEgQ2hh
    dmFuIChSUE0gU2lnbmluZyBLZXkpIDxwY2hhdmFuQHJlZGhhdC5jb20+iQE5BBMB
    AgAjBQJY0oHJAhsDBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQclXPPrdC
    Rs4mxwf6AwPEHK3ZWCUTjj9uJlVIM3lU+9F5aFOgns2cY6msR3Y+spOVVkBqq97V
    v3bgRbhU2W+0RXIRxnyOMn9LrBkcPCjujfPZ7gIBpfrJpOpH26PZEPyVvj07ZRv5
    5DFaJgccnr7LKwp22pn8byK1yK5BDZMg6/U9mK5MoRsfmc/fC4I25gT3aIBxV7hj
    swb7gbNOx3ZzQT7dJwQIFkznpY2XuKAwaZrpZNwttF74xW8oYjXatNsGNSNmNgFh
    7rtqAwBWTN54zg+qojk+eX4zMmldpWqvHATlh8cc4Wzj40bBI8Ifaq/QTl0dY3t2
    nzd1afgbwx4lTt5VjBQ8KJzSNSn0lbkBDQRY0oHJAQgApsX9jRxstyJMhaQr57Re
    voOkIT6z6mz8OpdGf2QHiXyVFYiRVv5njDl+hv9jtQ3XNmnInwi/Xs4OL5j6mE8r
    cetr4ngPowVeCbwqcZeP53S5/K4Klg+7G7Sut1oNQlh7qPbut/glgiu3zqwbl4rO
    Vs5iMGoQtZazQxHKby611Gka2yky/JSrnVLb7Hxsoe9/yT1+cmeelzv2hZA7cEqx
    XHykDAoiULepcfau3scUatZexyTNMne3nlLFSnVxz4PRy9/+l0jb2m2lA5Yl9U4G
    45JD+FJ/jflcSGW9wFD8B4Sgb8QAhVffbjzHrof0Bbxbxwc5ilYExXBtuSJao1Cd
    bwARAQABiQEfBBgBAgAJBQJY0oHJAhsMAAoJEHJVzz63QkbOIs4IALXiE2B+I2/D
    9//YhHGAXy7VQ3qKZBxuS0zxTHnzD+gLs+xIeCrLKJxpJ3beTxSdBRge/DQUkMXq
    F/j9vKHFFTf0Hx/IGj2ujdUdQ2ILoTJMsfQXprqPTAJ0t5oPGwIF+fBxmJjQ6DgM
    YbbQS2qMpK3YFCmKQHZQhwvn3r7jERWZpJr6pYYYkwqhmj1MXIxuJDGDgTH3VZl0
    g9FkYYhGy8dU4CFSoRGuTtcVX+VzI8/lU544K1HE7uLwkz40PP+zBpQ3QqxLC2MV
    voKkk10tyrv3xf+PimsnQmV3GKgfMoRLVTP0pP2YN8SS+aSGNPDwfKWKNkNRNc3/
    ZVDQUeETOh4=
    =aTMv
    -----END PGP PUBLIC KEY BLOCK-----
    
  • Import the exported public key into rpm database as follows.

    [root@localhost ~]# rpm --import RPM-GPG-KEY-pmanager
    
    [root@localhost ~]# rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'
            gpg-pubkey-fd431d51-4ae0493b --> gpg(Red Hat, Inc. (release key 2) <security@redhat.com>)
            gpg-pubkey-2fa658e0-45700c69 --> gpg(Red Hat, Inc. (auxiliary key) <security@redhat.com>)
            gpg-pubkey-b74246ce-58d281c9 --> gpg(Package Manager (RPM Signing Key) <pmanager@example.com>)
    
  • Edit the file ~/.rpmmacros in order to utilize the key.

    [root@localhost ~]# vi .rpmmacros
    [root@localhost ~]# cat .rpmmacros
    %_signature gpg
    %_gpg_path /root/.gnupg
    %_gpg_name Package Manager
    %_gpgbin /usr/bin/gpg2
    
  • Verify that the __gpg_sign_cmd is defined in --showrc option. Its not required to define this parameter in the ~/.rpmmacros above since its already defined in default macros unless there is a requirement to tweak the options for gpg singing command.

    [root@localhost ~]# rpm --showrc | grep __gpg_sign_cmd -A 5
    -13: __gpg_sign_cmd %{__gpg}
        gpg --no-verbose --no-armor
        %{?_gpg_digest_algo:--digest-algo %{_gpg_digest_algo}}
        --no-secmem-warning
        %{?_gpg_sign_cmd_extra_args:%{_gpg_sign_cmd_extra_args}}
        -u "%{_gpg_name}" -sbo %{__signature_filename} %{__plaintext_filename}
    
  • Sign the rpm.

    [root@localhost ~]# rpm --addsign test-1-0.x86_64.rpm
    Enter pass phrase:
    Pass phrase is good.
    test-1-0.x86_64.rpm:
    gpg: writing to `/var/tmp/rpm-tmp.JO74Hd.sig'
    gpg: RSA/SHA256 signature from: "B74246CE Package Manager (RPM Signing Key) <pmanager@example.com>"
    gpg: writing to `/var/tmp/rpm-tmp.hG5gUG.sig'
    gpg: RSA/SHA256 signature from: "B74246CE Package Manager (RPM Signing Key) <pmanager@example.com>"
    
    [root@localhost ~]# rpm --checksig test-1-0.x86_64.rpm
    test-1-0.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
    
    [root@localhost ~]# rpm -qp --qf '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{(none)}|}|\n' test-1-0.x86_64.rpm
    RSA/SHA256, Wed 22 Mar 2017 07:57:29 AM MDT, Key ID 7255cf3eb74246ce
    
  • rpm -K still shows generic output because SHA1 (and MD5) digests are an integral part of rpm packages,

  • Use the above command in order to confirm the sign algorithm.

See also

Comments