Tuesday, January 9, 2018

TLS and Mutual TLS handshake data overhead



I needed to test the data transfer involved in TLS and Mutual TLS handshake. I found bits of information on different sites. I thought it will be good to put all the information in one place and show the E2E flow.

There are 3 steps:
  • Prepare the client and server certificates
  • Configure NGINX
  • Test the handshake


Prepare the client and the server certificates


Generate client key pair and self-signed certificate


$/rnd/TLS/rsaclient: keytool -genkey -keyalg RSA -alias test -keystore clientselfsignedrsa.jks -validity 30 -keysize 2048

You will be prompted to enter password and few other details when generating certificates.

Generate server key pair and self-signed certificate


$/rnd/TLS/rsaserver: keytool -genkey -keyalg RSA -alias test -keystore serverselfsignedrsa.jks -validity 30 -keysize 2048

You will be prompted to enter password and few other details when generating certificates.

Extract client certificate and private key



$/rnd/TLS/rsaclient: keytool -importkeystore -srckeystore clientselfsignedrsa.jks -destkeystore pkcs12-keystore.p12 -deststoretype PKCS12

$/rnd/TLS/rsaclient: openssl pkcs12 -nokeys -in pkcs12-keystore.p12 -out rsaclientcert.pem

$/rnd/TLS/rsaclient: openssl pkcs12 -nocerts -nodes -in pkcs12-keystore.p12 -out rcsclientkey.key


Extract server certificate and private key


$/rnd/TLS/rsaserver: keytool -importkeystore -srckeystore serverselfsignedrsa.jks -destkeystore pkcs12-keystore.p12 -deststoretype PKCS12

$/rnd/TLS/rsaserver: openssl pkcs12 -nokeys -in pkcs12-keystore.p12 -out rsaservercert.pem

$/rnd/TLS/rsaserver: openssl pkcs12 -nocerts -nodes -in pkcs12-keystore.p12 -out rsaserverkey.key



Configure NGINX


The config file on mac is under /usr/local/etc/nginx

Edit the HTTPS server section and reload nginx (nginx -s reload)

    # HTTPS server
    #
    server {
        listen       8443 ssl;
        server_name  localhost;

        ssl_certificate      /rnd/TLS/rsaserver/rsaservercert.pem;
        ssl_certificate_key  /rnd/TLS/rsaserver/rsaserverkey.key;
ssl_client_certificate /rnd/TLS/rsaclient/rsaclientcert.pem;
        # Comment/Uncomment following line based on whether you want Mutual TLS or not.
ssl_verify_client on;
ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;

        ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }


Start wireshark capture with filter as "port 8443"

Test TLS Handshake


I have stripped some of the details from below trace to keep the size in check.

Mutual TLS (ssl_verify_client on;)


$ openssl s_client -connect localhost:8443 -cert /rnd/TLS/rsaclient/rsaclientcert.pem -key /rnd/TLS/rsaclient/rcsclientkey.key  -CAfile /rnd/TLS/rsaserver/rsaservercert.pem -state -debug
CONNECTED(00000003)
SSL_connect:before/connect initialization
.......
SSL_connect:SSLv2/v3 write client hello A
......
SSL_connect:SSLv3 read server hello A
......
SSL_connect:SSLv3 read server certificate A
......
SSL_connect:SSLv3 read server key exchange A
......
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
......
SSL_connect:SSLv3 write client certificate A
......
SSL_connect:SSLv3 write client key exchange A
......
SSL_connect:SSLv3 write certificate verify A
......
SSL_connect:SSLv3 write change cipher spec A
......
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
......
SSL_connect:SSLv3 read server session ticket A
......
SSL_connect:SSLv3 read finished A
---
Certificate chain
......
---
Server certificate
-----BEGIN CERTIFICATE-----
......
-----END CERTIFICATE-----
---
---
SSL handshake has read 2619 bytes and written 1621 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:

    Start Time: 1515538253
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)


Without Mutual TLS (comment ssl_verify_client on; in NGINX conf)



$ openssl s_client -connect localhost:8443 -cert /rnd/TLS/rsaclient/rsaclientcert.pem -key /rnd/TLS/rsaclient/rcsclientkey.key  -CAfile /rnd/TLS/rsaserver/rsaservercert.pem -state -debug
CONNECTED(00000003)
SSL_connect:before/connect initialization
......
SSL_connect:SSLv2/v3 write client hello A
......
SSL_connect:SSLv3 read server hello A
......
SSL_connect:SSLv3 read server certificate A
......
SSL_connect:SSLv3 read server key exchange A
......
SSL_connect:SSLv3 read server done A
......
SSL_connect:SSLv3 write client key exchange A
......
SSL_connect:SSLv3 write change cipher spec A
......
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
......
SSL_connect:SSLv3 read server session ticket A
......
SSL_connect:SSLv3 read finished A
---
Certificate chain
......
---
Server certificate
-----BEGIN CERTIFICATE-----
......
-----END CERTIFICATE-----
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1568 bytes and written 444 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
   
    Start Time: 1515538406
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)



Finally some numbers


Following is the summary of amount of data transferred during TLS handshake. This is relevant and may be a concern for OTA interfaces like cellular interfaces due to cost of data. These can be optimized with various TLS configuration on the server side. The objective of this exercise was to understand the data overhead in general.


  • TLS with RSA 2048 bit key - 2932 bytes
  • Mutual TLS with RSA 2048 bit key - 5384 bytes

  • TLS with ECC 256 bit key - 2356 bytes
  • Mutual TLS with ECC 256 bit key - 3847 bytes