21

Does anyone know how to use OpenSSL to generate certificates for the following public key types:

  1. DSA - For DHE_DSS key exchange.
  2. Diffie-Hellman - For DH_DSS and DH_RSA key exchange.
  3. ECDH - For ECDH_ECDSA and ECDH_RSA key exchange.
  4. ECDSA - For ECDHE_ECDSA key exchange.

Most that I can find online teaches you how to generate a RSA type certificate though.

1

3 Answers 3

28

(EC)DSA

For a DSA key pair, use this:

openssl dsaparam -out dsakey.pem -genkey 1024

where "1024" is the size in bits. The first DSA standard mandated that the size had to be a multiple of 64, in the 512..1024 range. Then another version deprecated sizes below 1024, so a valid DSA key size had length 1024 bits and nothing else. Current version specifies that a valid DSA key has length 1024, 2048 or 3072 bits. OpenSSL accepts other lengths. If you want to maximize interoperability, use 1024 bits.

For an ECDSA key pair, use this:

openssl ecparam -genkey -out eckey.pem -name prime256v1

To see what curve names are supported by OpenSSL, use: openssl ecparam -list_curves

(For optimal interoperability, stick to NIST curve P-256, that OpenSSL knows under the name "prime256v1".)

Once you have a DSA or ECDSA key pair, you can generate a self-signed certificate containing the public key, and signed with the private key:

openssl req -x509 -new -key dsakey.pem -out cert.pem

(Replace "dsakey.pem" with "eckey.pem" to use the EC key generated above.)


(EC)DH

For Diffie-Hellman (with or without elliptic curves), things are more complex, because DH is not a signature algorithm:

  • You will not be able to produce a self-signed certificate with a DH key.
  • You cannot either make a PKCS#10 request for a certificate with a DH key, because a PKCS#10 request is supposed to be self-signed (this self-signature is used as a proof of possession).

While OpenSSL, the library, has the support needed for issuing a certificate which contains a DH public key; this page may contain pointers. The challenge is to convince OpenSSL, the command-line tool, to do it. In the jungle of the OpenSSL documentation, I have not found a complete way to do it. Key pairs are easy enough to generate, though.

To generate a DH key pair, with the OpenSSL command-line tool, you have to do it in two steps:

openssl dhparam -out dhparam.pem 1024
openssl genpkey -paramfile dhparam.pem -out dhkey.pem

For an ECDH key pair, use this:

openssl ecparam -out ecparam.pem -name prime256v1
openssl genpkey -paramfile ecparam.pem -out ecdhkey.pem

However, it so happens that the format for certificates containing ECDH public keys is completely identical to the format for certificates containing ECDSA public keys; indeed, the format contains "an EC public key" without indication of the intended algorithm (ECDH or ECDSA). Therefore, any private key and certificates for ECDSA (private key for generating ECDSA signatures, certificate self-signed or signed by any other CA) will be fit for ECDH-* cipher suites.

The one case that I don't know how to produce with the OpenSSL command-line tool is a static Diffie-Hellman (non-EC) certificate. Note, though, that OpenSSL does not support SSL/TLS with static DH cipher suites either, so even if you could produce the certificate, it would not work with OpenSSL.

(And, in fact, nobody uses static DH in practice.)

7
  • One question though, why nobody uses static DH in practice? Practically,if I use DH-RSA, wouldn't it provides good security as well?
    – Ryu
    Oct 23, 2013 at 1:51
  • There is no known security issue with static DH. But nobody wants to use DH because it would be hard to test and would not promote interoperability, because... nobody uses DH. The source of the issue is that back in the early 1990s, when SSL and X.509 were in their infancy, the standard describing DH was not free (and is still not), so open source developers had a preference for RSA.
    – Tom Leek
    Oct 23, 2013 at 10:49
  • 1
    Also, DHE-RSA (or any other cipher suite with ephemeral DH or ECDH) provides Perfect Forward Secrecy, which is a nice thing to have.
    – Tom Leek
    Oct 23, 2013 at 10:50
  • Nitpick: the same EC key (or exactly SPKI) is usable for both ECDSA and ECDH, but the cert can also contain KeyUsage extension which can enable only one of them. openssl req -new -x509 can include KeyUsage depending on the config file used. Also FWLIW 1.0.2-beta does, and 1.0.2 release presumably will, finally implement static-DH; I don't know if someone actually requested it, or if it was just in the list of way-old leftovers getting cleaned up post-Heartbleed. Nov 1, 2014 at 12:55
  • OpenSSL has now added support for DH_RSA and DH_DSS ciphersuites in version 1.0.2 and 1.1.0+. These ciphersuites use certificates which contain a static DH key, but are signed with either RSA or DSA(DSS). They cannot be self-signed.
    – davenpcj
    Mar 9, 2017 at 15:49
10

Just dredging up an old question. I recently had need to create a DH cert for test purposes. This is how to do it. First create DH parameters and private key as per Tom's answer:

openssl dhparam -out dhparam.pem 1024
openssl genpkey -paramfile dhparam.pem -out dhkey.pem

Next create the public key file:

openssl pkey -in dhkey.pem -pubout -out dhpubkey.pem

Now you need a CSR file. CSRs are self signed which obviously can't be done for DH because DH is not a signing algorithm. But create one anyway for a different key (one that can sign, e.g. RSA). To create an RSA key and an associated CSR:

openssl genrsa -out rsakey.pem 1024
openssl req -new -key rsakey.pem -out rsa.csr

Finally, you generate the DH cert from the RSA CSR and the DH public key. It is not possible to create a self signed DH cert because (as noted above) DH is not a signing algorithm. Therefore you will need to have set up a CA certificate/key. In this example I assume you have previously created a CAkey.pem and CAcert.pem:

openssl x509 -req -in rsa.csr -CAkey CAkey.pem -CA CAcert.pem -force_pubkey dhpubkey.pem -out dhcert.pem -CAcreateserial

Your DH certificate will be in dhcert.pem

1
  • Just to note that force_pubkey is an OpenSSL 1.0.2+ option Mar 4, 2015 at 9:36
1

In fact, it is generally possible to issue X.509v3 certificates for these types of key pairs, too:

  • DH (Diffie-Hellman)
  • ECDH (Elliptic Curve Diffie-Hellman)
  • X25519 and X448 (Edwards Curves 25519 and 448, Key Agreement not signing!)

RSA is a cryptographic algorithm that allows you both, digital signing and enciphering/deciphering. To create a CSR (PKCS#10 request) for an RSA key pair (even it is used solely for encryption purposes), you can just use the private RSA key part to perform the necessary proof-of-possession, i.e. the self-signature. Obviously, this is not possible for keyagreement-only algorithms (DH, ECDH, X25519, and X448). There is just one very old RFC, RFC 2875 "Diffie-Hellman Proof-of-Possession Algorithms", which seems not to be used anywhere, though.

The standard OpenSSL command line tools are unable to accomplish the task, i.e. first using "openssl req" to generate the CSR (P10) and subsequently issuing the X.509v3 certificate using "openssl ca". Only the key generation can be performed, e.g. using "openssl genpkey" (for X25519/X448), "openssl ecparam", etc.

The ASN.1 module of PKCS#10 (see RFC 2986) states for the type CertificationRequest the digital signature as a BIT STRING without the OPTIONAL keyword, i.e. it is mandatory.

You would have to patch OpenSSL to either allow empty digital signatures (proof-of-possession) for key agreement algorithms or implement RFC 2875, which would mean a lot of work for all above mentioned algorithms.

2
  • 1
    ECDH and ECDSA in OpenSSL mean only X9.63 and X9.62 which use exactly the same key so you can create a CSR (with ECDSA) and resulting cert for either or both, as our local bear answered in 2013. For integer-DH (X9.42/PKCS3/RFC2631) and elliptic-XDH you can't create a proper CSR, but openssl x509 -req -force_pubkey ... can create a cert (since 2014) as Matt answered in 2015. Feb 28 at 0:39
  • Thanks. Anyway, there is RFC 2875, updated by RFC 6955 ("Diffie-Hellman Proof-of-Possession Algorithms") - OpenSSL does not implement it, though.
    – GermanDev
    Mar 3 at 21:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.