What is in a cipher suite name? or how to tell your RSA from your ephemeral

Why do we need stronger encryption?

  • To make keys more resilient to attack you need longer keys.
  • There are newer ways of providing better private keys than just using large prime numbers.   For example using the equation y**2= a* x**3 + b * x**2  + c*x + d.  Which you may recognize as a cubic equation, but comes under the name of Elliptic Curves(EC).  (For some values of a,b,c,d if you plot the curve it is an ellipse.)  These Elliptic Curves with small keys are harder to crack than RSA with longer.  They also use less resources during encryption and decryption.
  • Originally public/private certificates were used for both authentication and encryption.  This has the disadvantage that if I monitor your traffic for a year, then steal your private key (for example from the corporate backups) then I can decrypt all of your traffic.  You need to use a technique called Forward Secrecy to prevent this.   This gives assurances that session keys will not be compromised even if the private key of the server is compromised.   With Forward Secrecy
    • You use the public/private key for authentication, and generate a secret for the encryption.   A technique called Diffie-Hellman(DH) can be used to agree an agreed  common secret without a man-in-the middle being able to determine the secret key.   See Wikipedia  for a good description.   This is good – but repeated conversations may use the same common secret and over repeated use, people may be able to guess your key.
    • This problem is fixed by using Ephemeral(E) keys, known as one-time keys, which are valid for just one conversation.  A second conversation will get a different secret key.

You need to support and use ECDHE (Elliptic Curves – Diffie-Hellman – Ephemeral)  suites in order to enable forward secrecy (having the private key means you cannot decrypt the message) with modern web browsers.  Avoid the RSA key exchange unless absolutely necessary.

What does a cipher spec tell us?

This is a good web site which tells you what the cipher spec means.

A cipher spec describes the techniques to be used for authentication, encryption and hashing the data.  This is negotiated between the two ends when setting up a TLS handshake.  The conversation is like “Client: I support the following cipher specs; Server: I like this one…”,  or “Client: I support the following cipher specs; Server: hmm none match”

If you look at the names of cipher suites available with TLS v1.2 you find names like

  • TLS_RSA_WITH_…  this is for a key with public certificate generated with RSA
  • TLS_ECDH_RSA_WITH… this is for a key with public certificate generated with Elliptic Curve(EC) and uses Diffie-Hellman(DH)
  • TLS_ECDHE_ECDSA_WITH…  this is for a key with public certificate generated with Elliptic Curve(EC) and uses Diffie-Hellman(DH) and Ephemeral key (E)

I found this document which is a good introduction to cipher specs TLS 1.2, TLS 1.3 etc

A cipher spec which I use a lot is TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384

Let me break that down into the components

  • TLS indicates the protocol ( old versions might have SSL)
  • ECDHE : Key Exchange Algorithm.  What is used to generate a secret number. Think of a telephone conversation between the UK and China. “Should we talk in English or Chinese”.  “I prefer English”. “OK my information is …”.   In this example  we have  ECDHE:  Elliptic Curve, Diffie-Hellman, Ephemeral.   This can be
    • ECDHE
    • ECDH
    • RSA
    • DH
  • ECDSA:  Authentication/Digital Signature Algorithm: What sort of certificate can be used.
    • ECDSA the server public key is an Elliptic Curve signifies.  ECDSA is Elliptic Curve + Digital Signing Algorithm.   The TLS spec says it should be signed using a CA with EC public certificate – but it works even if it is signed with an RSA certificate
    • RSA the server public key is created with RSA public certificate.  The TLS spec says it should be signed using a CA with RSA public certificate – but it works even if it is signed with an ECDSA certificate
  • “WITH” splits the authentication and encryption from the encryption of the data itself.
  • AES_256_CBC indicates the bulk encryption algorithm: Once the handshake has completed, the encryption of the payload is done using symmetric encryption.  They keys are determined during the handshake.    AES_256 is a symmetric encryption with a 256 bit key using Cipher Block Chaining. (CBC is like using a “running total” of the data encrypted so far, as an input to the encryption).   TLSv1.3 drops support for CBC;  GCM can be used instead. It is faster and can exploit pipeline processors.
  • SHA384 indicates the algorithm for hashing the message (MAC =  Message Authentication Code).  This algorithm is used as  pseudo random function during the handshake.

Notes:

  • DSS is a different authentication algorithm. For example TLS_DHE_DSS…   It also stands for Digital for Digital Signature Standard which covers all algorithms – so a touch confusing.
  • Because RSA tends to be used for authentication and encryption, I think of TLS_RSA_WITH… as TLS_RSA_RSA_WITH.   So the secret number generation algorithm is RSA, and then the certificate with an RSA public key is used.

For TLS 1.3 the cipher specs are like  TLS_AES_256_GCM_SHA384 because the key exchange algorithm will be either ECDHE or RSA.

How do I create a certificate with Elliptic Curve (or RSA)

Why would I want to use Elliptic Curve?

Some ciphers are considered stronger than others.  For example certificates with Elliptic Curve algorithms are now considered better than using the well known RSA.    They are more secure and use less resources.  Over time certificates with Elliptic Curves may become the norm.  See here.

If you change to use a different algorithm you need to make sure that both ends of the TLS connection support it.   If a cipher spec beginning with TLS_ECDHE is the only cipher spec available, it may not work with certificates with RSA.

When you create a certificate you first create the private key, and then make the public certificate.  You can sometimes combine this into one operation.

To make a private key using Elliptic Curve

Use

openssl genpkey -out $name.key.pem -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -aes256 -pass file:password.file

where

  • $name – I create the certificate in a shell script.  As the name of the certificate is used in many places – it is best to use a shell variable to hold the short certificate name.
  • -algorithm EC says this is an Elliptic Curve
  •  P-256  is the Elliptic Curve definition to use.   This is a popular key;  it has a key length of 256.  It is also known as prime256v1.
  • -aes256 -pass file:password.file says encrypt the private key using the aes 256 cipher spec (there are others available) – and use the password in the file. You need this when doing working with private key and public certificate, for example creating the certificate request.  If you do not specify -aes256 (or equivilant)  etc the private key is not encrypted, and so could be used if stolen.   This is not used during TLS handshakes.

Or (the old syntax )

openssl ecparam -name prime256v1 -genkey -noout -out $name.key.pem …

You then create the request and get the request signed (this is common to all requests)

name=”eccert”
openssl req -config xxx.config -new -key $name.key.pem -out $name.csr -outform PEM -subj “/C=GB/O=cpwebuser/CN=”$name -passin file:password.file -passout file:password.file
openssl ca -config openssl-ca-user.cnf -policy signing_policy  -md sha256 -cert ca2.pem -keyfile ca2.key.pem -out $name.pem -in $name.csr  -extensions clientServer

The command openssl x509 -in eccert.pem -text -noout|less displays the certificate and gives

Subject Public Key Info:
  Public Key Algorithm: id-ecPublicKey
    Public-Key: (256 bit)
     pub:
       04:...
       ce:60:63:03:84
     ASN1 OID: prime256v1
     NIST CURVE: P-256

During the TLS handshake, this can be processed by CipherSpecs TLS_EC*, such as TLS_ECDH… and TLS_ECDHE…

If you use openssl ecparam -name secp521r1  this gives Public Key Algorithm: id-ecPublicKey Public-Key: (521 bit)

To make a private key using RSA

Use

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out $name.key.pem -aes256 -pass pass:password

Or (the old syntax)

openssl genrsa -out $name.key.pem 4096 -aes256 -pass pass:password

where

  • rsa_keygen_bits:4096  – is the size of the key to use.
  • -aes256 -pass pass:password says encrypt the private key  using the aes 256 cipher spec (there are others available) – the password is password.  You need this when doing working with private key and public certificate.  This is not used during TLS handshakes.

You make the request and get it signed (the statements below are the same as for the EC certificate)

name=”rsa”
ca=”ca2″
openssl req -config xxx.config -new -key $name.key.pem -out $name.csr -outform PEM -subj “/C=GB/O=cpwebuser/CN=”$name -passin file:password.file -passout file:password.file
openssl ca -config openssl-ca-user.cnf -policy signing_policy  -md sha256 -cert $ca.pem -keyfile $c2.key.pem -out $name.pem -in $name.csr  -extensions clientServer

The command openssl x509 -in rsa.pem -text -noout|less displays the certificate and gives

Subject Public Key Info:
  Public Key Algorithm: rsaEncryption
   RSA Public-Key: (4096 bit)
    Modulus:
      00:d0:88:d2:d0:86:34:82:bb:1a:7b:a0:6d:37:fd:
      ... 
     1e:3d:31
    Exponent: 65537 (0x10001)

During the TLS handshake, this can be processed by CipherSpecs TLS_RSA*.

Changing the Signature Algorithm:

With a java program, you can use java.security to limit which Security Algorithms are allowed during the handshake, and so prevent certificates from being used.

As part of the TLS handshake there is a conversation about the encryption of the certificate.  For example listing an RSA certificate gives

Signature Algorithm: sha256WithRSAEncryption

You can change this by using

openssl ca … -md sha384

This gives

Signature Algorithm: sha384WithRSAEncryption

For an Elliptic Curve certificate this was

Signature Algorithm: ecdsa-with-SHA256  with the default -md (sha256) or Signature Algorithm: ecdsa-with-SHA384 ( when -md sha384 is specified)

Storing the certificate

I used a script to generate my certificate.  In this script I had

  • openssl x509 -in $name.pem -text -noout|less to display the certificate, and check the options
  • openssl pkcs12 -export -inkey $name.key.pem -in $name.pem -out $name.p12 -CAfile ca256.pem -chain -name $name -passout file:password.file -passin file:password.file to create the *.p12 file with the certificate and CA chain, so it can be used by java, and curl etc
  • certutil -D $sql -n $name remove the certificate from the Chrome browser keystore.  Where sql=”-d sql:/home/colinpaice/snap/chromium/current/.pki/nssdb”
  • pk12util -i $name.p12 $sql -W password to add the  .p12 created above into the Chromium keystore (along with its CA chain)

Using the certificate

For my java programs I used the certificate keystore sssks.p12 with -Djavax.net.ssl.keyStore=/home/colinpaice/ssl/ssl2/sssks.p12 -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.keyStoreType=pkcs12 or for mqwebuser.xml  <keyStore id=”defaultKeyStore” location=”/home/colinpaice/ssl/sssks.p12″ type=”pkcs12″ password=”password”/>