X.509 certificates are an application of digital signatures for identity verification. TLS uses X.509 to create a chain of trust from a trusted CA to a service certificate. An X.509 certificate binds a public key to a subject by way of a secure and verifiable signature made by a certificate authority (CA).
A signature algorithm has two parts: a public key signing algorithm (determined by the type of the CA’s signing key) and a collision-resistant hash function. The hash function digests the certified data into a small value that is hard to find collision for, which gets signed.
Computers keep getting faster and attacks on cryptography always get better. So over time older algorithms need to be deprecated, and newer algorithms adopted for use with X.509. In the past the MD5 and SHA-1 digests were often used with X.509, but today SHA-256 (a variant of SHA-2) is the most used algorithm. SHA-256 is also the weakest digest accepted by many programs (e.g. web browsers). Stronger variants of SHA-2 are widely supported.
FreeIPA currently uses the
sha256WithRSAEncryption signature algorithm by default. Sometimes we get asked about how to use a stronger digest algorithm. In this article I’ll explain how to do that and discuss the motivations and implications.
Implications of changing the digest algorithm
Unlike re-keying or changing the CA’s Subject DN, re-issuing a certificate signed by the same key, but using a different digest, should Just Work. As long as a client knows about the digest algorithm used, it will be able to verify the signature. It’s fine to have a chain of trust that uses a variety of signature algorithms.
Configuring the signature algorithm in FreeIPA
The signature algorithm is configured in each Dogtag certificate profile. Different profiles can use different signature algorithms. The public key signing algorithm depends on the CA’s key type (e.g. RSA) so you can’t change it; you can only change the digest used.
Modifying certificate profiles
Before FreeIPA 4.2 (RHEL 7.2), Dogtag stored certificate profile configurations as flat files. Dogtag 9 stores them in
/var/lib/pki-ca/profiles/ca and Dogtag >= 10 stores them in
/var/lib/pki/pki-tomcat/ca/profiles/ca. When Dogtag is using file-based profile storage you must modify profiles on all CA replicas for consistent behaviour. After modifying a profile, Dogtag requires a restart to pick up the changes.
As of FreeIPA 4.2, Dogtag uses LDAP-based profile storage. Changes to profiles get replicated among the CA replicas, so you only need to make the change once. Restart is not required. The
ipa certprofile plugin provides commands for importing, exporting and modifying certificate profiles.
Because of the variation among versions, I won’t detail the process of modifying profiles. We’ll look at what modifications to make, but skip over how to apply them.
Profile configuration changes
For service certificates, the profile to modify is
caIPAserviceCert. If you want to renew the CA signing cert with a different algorithm, modify the
caCACert profile. The relevant profile policy components are
signingAlgDefaultImpl. Look for these components in the profile configuration:
policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl policyset.serverCertSet.8.constraint.name=No Constraint policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl policyset.serverCertSet.8.default.name=Signing Alg policyset.serverCertSet.8.default.params.signingAlg=-
policyset.<name>.<n>.default.params.signingAlg parameter; replace the
- with the desired signing algorithm. (I set it to
SHA512withRSA.) Ensure that the algorithm appears in the
policyset.<name>.<n>.constraint.params.signingAlgsAllowed parameter (if not, add it).
After applying this change, certificates issued using the modified profile will use the specified algorithm.
After modifying the
caIPAserviceCert profile, we can renew the HTTP certificate and see that the new certificate uses
getcert list to find the Certmonger tracking request ID for this certificate. We find the tracking request in the output:
... Request ID '20171109075803': status: MONITORING stuck: no key pair storage: type=NSSDB,location='/etc/httpd/alias',nickname='Server-Cert',token='NSS Certificate DB',pinfile='/etc/httpd/alias/pwdfile.txt' certificate: type=NSSDB,location='/etc/httpd/alias',nickname='Server-Cert',token='NSS Certificate DB' CA: IPA issuer: CN=Certificate Authority,O=IPA.LOCAL subject: CN=rhel69-0.ipa.local,O=IPA.LOCAL expires: 2019-11-10 07:53:11 UTC ... ...
So the tracking request ID is
20171109075803. Now resubmit the request:
[root@rhel69-0 ca]# getcert resubmit -i 20171109075803 Resubmitting "20171109075803" to "IPA".
After a few moments, check the status of the request:
[root@rhel69-0 ca]# getcert list -i 20171109075803 Number of certificates and requests being tracked: 8. Request ID '20171109075803': status: MONITORING stuck: no key pair storage: type=NSSDB,location='/etc/httpd/alias',nickname='Server-Cert',token='NSS Certificate DB',pinfile='/etc/httpd/alias/pwdfile.txt' certificate: type=NSSDB,location='/etc/httpd/alias',nickname='Server-Cert',token='NSS Certificate DB' CA: IPA issuer: CN=Certificate Authority,O=IPA.LOCAL subject: CN=rhel69-0.ipa.local,O=IPA.LOCAL expires: 2019-11-11 00:02:56 UTC ...
We can see by the
expires field that renewal succeeded. Pretty-printing the certificate shows that it is using the new signature algorithm:
[root@rhel69-0 ca]# certutil -d /etc/httpd/alias -L -n 'Server-Cert' Certificate: Data: Version: 3 (0x2) Serial Number: 12 (0xc) Signature Algorithm: PKCS #1 SHA-512 With RSA Encryption Issuer: "CN=Certificate Authority,O=IPA.LOCAL" Validity: Not Before: Fri Nov 10 00:02:56 2017 Not After : Mon Nov 11 00:02:56 2019 Subject: "CN=rhel69-0.ipa.local,O=IPA.LOCAL"
It is using SHA-512/RSA. Mission accomplished.
In this article I showed how to configure the signing algorithm in a Dogtag certificate profile. Details about how to modify profiles in particular versions of FreeIPA was out of scope.
In the example I modified the default service certificate profile
caIPAserviceCert to use
SHA512withRSA. Then I renewed the HTTP TLS certificate to confirm that the configuration change had the intended effect. To change the signature algorithm on the FreeIPA CA certificate, you would modify the
caCACert profile then renew the CA certificate. This would only work if the FreeIPA CA is self-signed. If it is externally-signed, it is up to the external CA what digest to use.
In FreeIPA version 4.2 and later, we support the addition of custom certificate profiles. If you want to use a different signature algorithm for a specific use case, instead of modifying the default profile (
caIPAserviceCert) you might add a new profile.
The default signature digest algorithm in Dogtag is currently SHA-256. This is appropriate for the present time. There are few reasons why you would need to use something else. Usually it is because of an arbitrary security decision imposed on FreeIPA administrators. There are currently no plans to make the default signature algorithm configurable. But you can control the signature algorithm for a self-signed FreeIPA CA certificate via the
In the introduction I mentioned that the CA’s key type determines the public key signature algorithm. That was hand-waving; some key types support multiple signature algorithms. For example, RSA keys support two signature algorithms: PKCS #1 v1.5 and RSASSA-PSS. The latter is seldom used in practice.
The SHA-2 family of algorithms (SHA-256, SHA-384 and SHA-512) are the "most modern" digest algorithms standardised for use in X.509 (RFC 4055). The Russian GOST R digest and signature algorithms are also supported (RFC 4491) although support is not widespread. In 2015 NIST published SHA-3 (based on the Keccak sponge construction). The use of SHA-3 in X.509 has not yet been standardised. There was an Internet-Draft in 2017, but it expired. The current cryptanalysis of SHA-2 suggests there is no urgency to move to SHA-3. But it took a long time to move from SHA-1 (which is now insecure for applications requiring collision resistance) to SHA-2. Therefore it would be good to begin efforts to standardise SHA-3 in X.509 and add library/client support as soon as possible.