Reputation: 10051
I'm creating CSRs for new certificates using OpenSSL. For modern compatibility, I've gone with EC (secp521r1
) certificates. While googling around, I found two different ways of creating the CSR.
I can create a private key explicitly
openssl ecparam -name secp521r1 -genkey -param_enc explicit -out private.key
openssl req -new -sha256 -nodes -key private.key -out sslcert.csr -config san.cnf
or I can create a private key with the request
openssl ecparam -name secp521r1 > ec.file
openssl req -new -sha256 -nodes -newkey ec:ec.file -keyout private.key -out sslcert.csr -config san.cnf
Both of these methods seem to create valid CSR files (I have tested them here).
My question is whether one of the methods above is better/safer? I noticed that the private key file generated by the first method is larger, and so is the CSR file.
For example, when I inspect the CSR using openssl req -noout -text -in sslcert.csr
, the CSR generated by the first method contains much more detailed information about the key, with a section for pub
, Prime
, A
, B
, Generator
, Order
, Cofactor
, Seed
, but there is no mention of secp521r1
.
However, the CSR generated by the second method contains only pub
and a ASN1 OID: secp521r1
. Are these differences important if I'm creating certificates for HTTPS use?
Many thanks!
Upvotes: 0
Views: 1260
Reputation: 102246
For example, when I inspect the CSR using openssl req -noout -text -in sslcert.csr, the CSR generated by the first method contains much more detailed information about the key, with a section for pub, Prime, A, B, Generator, Order, Cofactor, Seed, but there is no mention of secp521r1.
These are called "domain parameters". They explicitly list the modulus, the coefficients, the generator, the public point, etc.
However, the CSR generated by the second method contains only pub and a ASN1 OID: secp521r1. Are these differences important if I'm creating certificates for HTTPS use?
A name like ASN1 OID: secp521r1 is called a "named curve".
The IETF's PKIX and TLS working group say domain parameters and named curves are not the same thing. The PKIX group is responsible for the internet's PKI and certificates. There have been several discussions about this on the TLS working group mailing lists.
If you don't use a named curve, then your clients and servers will fail to connect to one another even the the domain parameters and named curves are equivalent. You will get errors similar to "no shared cipher suites" which will result in a TLS alert.
Here are the errors you get when using s_client
and s_server
during testing if you mix and match domain parameters with named curves:
Client (s_client):
139925962778272:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1256:SSL alert number 40
139925962778272:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:
Server (s_server):
140339533272744:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1353:
For interoperability you should always explicitly set named_curve
. Also see Elliptic Curve Cryptography | Named Curves on the OpenSSL wiki.
Both of these methods seem to create valid CSR files (I have tested them here).
They kind of do, but they don't inter-operate well if they are mixed/matched.
For modern compatibility, I've gone with EC (
secp521r1
) certificates...
I have not surveyed it recently, but secp256r1
is (was?) the most popular one. That may have changed but I don't recall reading it anywhere. Maybe a scan of the Alexis top 1 Million will give you an idea or answer.
The 2016 paper TLS in the wild: An Internet-wide analysis of TLS-based protocols for electronic communication says:
Looking at the elliptic curves that are used in ECDHE key exchanges reveals that 97.2% of connections use the secp256r1 curve, followed by 2% using secp384r1 and 0.78% using sect571r1.
Upvotes: 1