RPM (Red Hat Package Manager) is a package management system used in Linux distributions, particularly those based on Red Hat, such as Fedora and CentOS. RPM packages are software bundles that contain executable files, libraries, documentation, and other resources required for a specific application or service to function correctly on a Linux system.
RPM packages are compressed archives that follow a specific file format and naming convention. They typically have the extension “.rpm” and can be installed, upgraded, or removed using RPM package management tools.
The RPM package format is widely used in many Linux distributions, and it simplifies software management by providing a standardized and reliable method for packaging and distributing software.
Signing an RPM package, in short: generate an HSM-backed GPG key pair, import it into your GPG keyring via a PKCS#11 bridge, then run the RPM Signer utility with your key name, fingerprint, and issuer email. The tool produces a detached signature file, a separate artifact linked to the package, distinct from the traditional
rpm --addsignmodel that embeds the signature directly in the RPM header.
Key Takeaways
- This tool produces a detached
.sigfile rather than embedding the signature in the RPM header. That means standard RPM tooling (rpm -K,rpm --checksig) won’t verify it directly; verification must go through the RPM Signer utility’s ownverifysubcommand instead. - The key fingerprint (
-f) must be the exact hex fingerprint of the GPG key generated on the HSM, not a key name or email; a mismatch here is a common source of signing failures.
Environment Matrix
| Component | Requirement |
|---|---|
| OS | Linux (Debian/Ubuntu shown; RPM-based distributions like Fedora/CentOS are the typical target for the packages themselves) |
| HSM integration | PKCS#11-compatible HSM (nCipher/nfast shown) bridged to GPG via gnupg-pkcs11-scd |
| Python dependencies | crypto==1.4.1, cryptography==40.0.2, pycryptodome==3.16.0, requests==2.28.2 |
| Client authentication | SSL Client Authentication Certificate in PKCS12 format (.p12 or .pfx) |
| Supported hash algorithms | SHA224, SHA256 (default), SHA384, SHA512 |
| Signature format | Detached signature file, not embedded in the RPM header |
Overview
To sign RPM packages with GPG keys, the following steps are typically involved:
-
Generate GPG Key Pair
The package maintainer or distributor generates a GPG key pair consisting of a private key and a corresponding public key. The private key is kept secure (preferably in HSM) and should not be shared, while the public key can be distributed widely.
-
Configure RPM Signing
The GPG public key is added to the RPM package manager’s keyring, allowing it to verify the packages signed with the corresponding private key. This step ensures that the package manager recognizes the GPG key as trusted.
-
Sign RPM Packages
The package maintainer signs the RPM packages using the private key associated with the GPG key pair. This process generates a digital signature for each package.
-
Verify RPM Packages
When the RPM package manager encounters a signed package, it uses the GPG public key to verify the package’s signature. It checks whether the signature is valid and matches the package’s content, ensuring that it hasn’t been modified or tampered with since it was signed.
RPM signing with GPG keys adds additional security to RPM packages. It helps to establish the authenticity and integrity of the packages by confirming that they were signed by the entity possessing the private key associated with the GPG public key. This method allows users and systems to verify the trustworthiness of RPM packages before installation and guards against unauthorized modifications or malicious tampering.
Prerequisites
-
Generate key pair on HSM
-
Change directory to /opt/nfast/bin
$ cd /opt/nfast/bin -
Execute the command and enter the appropriate details
$ ./generatekey pkcs11 selfcert=yesNote: Remember your key’s name and email address, as they will be required in the subsequent steps.
-
Execute command
$ ./ckcerttool -n -f pkcs11_ua4335d6933d9809f048dcf4bc47c90194f2f7ba4b_selfcert -k ua4335d6933d9809f048dcf4bc47c90194f2f7ba4b -L rpmtestHere, the “-f” option corresponds to “self-cert,” the “-k” option refers to the key, and the “-L” parameter should match the Key name entered previously.
-
Install the gnupg-pkcs11-scd
$ sudo apt-get install gnupg-pkcs11-scdNote: If you encounter any issues with executing the “sudo apt-get install” command, try running the following command beforehand.
$ sudo apt-get update && sudo apt-get upgrade -y -
Configure gnupg agent
-
Edit the following lines in the gpg-agent.conf
$ nano ~/.gnupg/gpg-agent.conf
- Enter the below lines and save the file
scdaemon-program /usr/bin/gnupg-pkcs11-scd
pinentry-program /usr/bin/pinentry -
Edit the following lines in the gnupg-pkcs11-scd.conf
$ nano ~/.gnupg/gnupg-pkcs11-scd.conf
- Enter the below lines and save the file
providers p1
provider-p1-library /opt/nfast/toolkits/pkcs11/libcknfast.so
-
-
Reload the agent
$ gpg-agent --server gpg-connect-agent <<EOF
> RELOADAGENT
> EOF -
Get the GPG KEY-FRIENDLY string (of the newly generated key)
-
Retrieve card details
$ gpg --card-status -
Retrieve key-friendly names and certificates
$ gpg-agent --server gpg-connect-agent << EOF
> SCD LEARN
> EOF
-
-
Import the key into GPG 2 keyring
$gpg --expert --full-generate-keyNote: Enter key-friendly generated previously under the “Enter the keygrip” parameter.
-
To check the key in the gpg key ring, execute the below command.
$ gpg --list-keys
-
-
Set environment variables for the SSL Client Authentication Certificate path and certificate password.
Note: SSL Client Authentication Certificate should be in the PKCS12 format (.p12 or .pfx)
Execute the bellow command to set environment variables:
-
Mac or Linux
$ export EC_Client_Auth=path_to_ssl_certificate
$ export EC_Client_Pass=your_client_certificate_password -
Windows
$ set EC_Client_Auth=path_to_ssl_certificate
$ set EC_Client_Pass=your_client_certificate_password
-
-
Install all the following requirements:
- crypto==1.4.1
- cryptography==40.0.2
- pycryptodome==3.16.0
- requests==2.28.2
How to use the RPM Signer utility?
Get the version of the RPM Signer Utility
Execute the below command
$ python3 rpmsigner.py -v or $ python3 rpmsigner.py --version
Sign an RPM package
Execute the below sign subcommand to sign an RPM package.
Syntax:
python3 rpmsigner.py sign <file_to_be_signed> -u <user_name> -k <key_name> -i <issuer_email> -f <key_fingerprint> -a <algorithm> [-o <output_sig_file_name>]
Parameters:
- sign: RPM Package to be signed.
- -u: A username on Encryption Consulting Code Signing Server.
- -k: Key/certificate name for signing/verification provided by Encryption Consulting Code Signing server.
- -i: User email address used to generate key pair.
- -f: gpg key fingerprint in hex format.
-
-a:
Algorithm to be used for signing. One of the below options to be used:
- SHA224
- SHA256 (Default)
- SHA384
- SHA512
If the algorithm is not provided, it will use SHA256 as a default.
- -o: Output file to store signature. This is an optional parameter. If this option is provided, a signature file will be generated as per the given name <file_to_be_signed>.sig
- -h: Display help.
- -v: Display verbose logs.
Example:
python3 rpmsigner.py sign test_rpm_signer.rpm -u admin -k RPMtestcert -i [email protected] -f
3E633D3878815FAC111CF488FC15CA0088C43155 -a SHA256 -o myFile.sig
Verify an RPM package
Execute the below verify subcommand to verify the signature of an RPM package.
Syntax:
python3 rpmsigner.py verify <file_to_be_verified> -u <user_name> -k <key_name> -i <issuer_email> -f <key_fingerprint> -a <algorithm>
Example:
python3 rpmsigner.py verify test_rpm_signer.rpm -u admin -k RPMtestcert -i [email protected] -f
3E633D3878815FAC111CF488FC15CA0088C43155 -a SHA256
A successful verification returns a confirmation that the signature matches the package content and the specified key; a mismatch or tampering returns a failure indicating the package should not be trusted. Since this is a detached signature rather than an embedded RPM header signature, always verify through this utility rather than assuming rpm -K will report anything about it.
Common Errors
| Error | Likely Cause | Fix |
|---|---|---|
| Key not found / fingerprint mismatch | The -f value doesn’t exactly match the hex fingerprint of the HSM-backed GPG key | Re-run gpg --list-keys to confirm the exact fingerprint rather than reusing a value from memory or an old command |
| Authentication failure connecting to signing server | EC_Client_Auth or EC_Client_Pass environment variables not set or incorrect | Re-verify both are exported in the current shell session, not just set in an unsourced script |
| gpg-agent fails to find the scdaemon | gpg-agent.conf or gnupg-pkcs11-scd.conf paths are misconfigured, or the agent wasn’t reloaded after editing | Confirm the scdaemon-program path is correct and re-run the RELOADAGENT command after any config change |
CI/CD Use and Cleanup
For repeated signing in a pipeline, set EC_Client_Auth and EC_Client_Pass as pipeline secrets rather than hardcoding them, and pin the exact key fingerprint as a pipeline variable rather than looking it up interactively each run. Verify idempotency by running the verify subcommand immediately after signing and failing the build on anything other than a successful match, rather than trusting the sign command’s exit code alone.
For cleanup: if the .p12/.pfx client authentication certificate was copied to a build agent for testing, remove it once the pipeline is confirmed working, and prefer injecting it as a pipeline secret at runtime instead.
Want to know how we can assist you?
Encryption Consulting’s CodeSign Secure provides organizations with a comprehensive code-signing solution tailored to their unique requirements. By utilizing this solution, organizations can establish a strong code-signing policy that effectively mitigates security risks and ensures the authenticity of their software. Our product streamlines the code-signing process and offers a range of features designed to enhance security.
One key feature of CodeSign Secure is secure key management. It enables organizations to securely store their private keys of the code-signing certificate by integrating with industry-leading Hardware Security Modules (HSMs) that are FIPS certified. This integration eliminates the potential risks associated with stolen, corrupted, or misused keys, as the private keys never leave the HSM during the code signing operation.
Frequently Asked Questions
Will `rpm -K` or `rpm –checksig` verify a package signed with this tool?
No. This tool produces a detached signature file rather than embedding the signature in the RPM header, which is what standard RPM tooling checks. Verify using the RPM Signer utility’s own verify subcommand instead.
What exactly goes in the -f (fingerprint) parameter?
The full hex fingerprint of the GPG key generated on the HSM, obtained via gpg --list-keys, not the key name or email address used for the other parameters.
