How do I list the SSL/TLS cipher suites a particular website offers?

3,791

Solution 1

I wrote a bash script to test cipher suites. It gets a list of supported cipher suites from OpenSSL and tries to connect using each one. If the handshake is successful, it prints YES. If the handshake isn't successful, it prints NO, followed by the OpenSSL error text.

#!/usr/bin/env bash

# OpenSSL requires the port number.
SERVER=$1
DELAY=1
ciphers=$(openssl ciphers 'ALL:eNULL' | sed -e 's/:/ /g')

echo Obtaining cipher list from $(openssl version).

for cipher in ${ciphers[@]}
do
echo -n Testing $cipher...
result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1)
if [[ "$result" =~ ":error:" ]] ; then
  error=$(echo -n $result | cut -d':' -f6)
  echo NO \($error\)
else
  if [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher    :" ]] ; then
    echo YES
  else
    echo UNKNOWN RESPONSE
    echo $result
  fi
fi
sleep $DELAY
done

Here's sample output showing 3 unsupported ciphers, and 1 supported cipher:

[@linux ~]$ ./test_ciphers 192.168.1.11:443
Obtaining cipher list from OpenSSL 0.9.8k 25 Mar 2009.
Testing ADH-AES256-SHA...NO (sslv3 alert handshake failure)
Testing DHE-RSA-AES256-SHA...NO (sslv3 alert handshake failure)
Testing DHE-DSS-AES256-SHA...NO (sslv3 alert handshake failure)
Testing AES256-SHA...YES

EDIT: Add flexibility as host and port are provided as parameter to the script

Solution 2

Nmap with ssl-enum-ciphers

There is no better or faster way to get a list of available ciphers from a network service. Plus, nmap will provide a strength rating of strong, weak, or unknown for each available cipher.

First, download the ssl-enum-ciphers.nse nmap script (explanation here). Then from the same directory as the script, run nmap as follows:

List ciphers supported by an HTTP server

$ nmap --script ssl-enum-ciphers -p 443 www.example.com

List ciphers supported by an IMAP server

$ nmap --script ssl-enum-ciphers -p 993 mail.example.com

Here is a snippet of output from a Dovecot IMAP server:

993/tcp open  imaps
| ssl-enum-ciphers:
|   SSLv3:
|     ciphers:
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_IDEA_CBC_SHA - weak
...
|   TLSv1.0:
|     ciphers:
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_IDEA_CBC_SHA - weak
...
|_  least strength: weak

Nmap done: 1 IP address (1 host up) scanned in 1.03 seconds

Solution 3

Is there a tool that can test what SSL/TLS cipher suites a particular website offers?

Yes, you could use the online tool on SSL Labs' website to query the Public SSL Server Database.

Here is a snippet of information that it provides:

alt text

(screenshot from results of google.com)

Solution 4

sslscan is a nice little utility.

It tests connecting with TLS and SSL (and the build script can link with its own copy of OpenSSL so that obsolete SSL versions are checked as well) and reports about the server's cipher suites and certificate.

Example output for google.com (trimmed down for readability):

$ sslscan google.com
Testing SSL server google.com on port 443

 TLS renegotiation:
Secure session renegotiation supported

  TLS Compression:
Compression disabled

  Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.1 not vulnerable to heartbleed
TLS 1.0 not vulnerable to heartbleed

  Supported Server Cipher(s):
Preferred TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA          Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-RC4-SHA             Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  AES128-GCM-SHA256
Accepted  TLSv1.2  128 bits  AES128-SHA
<snip>
Preferred TLSv1.1  128 bits  ECDHE-RSA-AES128-SHA          Curve P-256 DHE 256
Accepted  TLSv1.1  128 bits  ECDHE-RSA-RC4-SHA             Curve P-256 DHE 256
Accepted  TLSv1.1  128 bits  AES128-SHA
<snip>
Preferred TLSv1.0  128 bits  ECDHE-RSA-AES128-SHA          Curve P-256 DHE 256
Accepted  TLSv1.0  128 bits  ECDHE-RSA-RC4-SHA             Curve P-256 DHE 256
Accepted  TLSv1.0  128 bits  AES128-SHA
<snip>
Preferred SSLv3    128 bits  RC4-SHA
Accepted  SSLv3    128 bits  RC4-MD5
<snip>

  SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
RSA Key Strength:    2048

Subject:  *.google.com
Altnames: DNS:*.google.com, DNS:*.android.com, <snip>
Issuer:   Google Internet Authority G2

Not valid before: Apr  7 08:24:31 2016 GMT
Not valid after:  Jun 30 08:20:00 2016 GMT

Solution 5

Since this is such a great reference thread for SSL scanning tools, I'll list CipherScan which was created a year ago and can also identify problems with key exchange ciphers. https://github.com/jvehent/cipherscan

If you want my fork which supports SNI and FreeBSD, the URL is https://github.com/oparoz/cipherscan

It's a script which calls openssl s_client and supports using your own OpenSSL binary so that you can test upcoming features or new ciphers (chacha20+poly1305 per example).

It also lets you connect to any port you want and use starttlss.

Here is a typical output

# ./cipherscan -o ./openssl api.mycompany.com:443
...................
prio  ciphersuite                  protocols              pfs_keysize
1     DHE-RSA-AES256-GCM-SHA384    TLSv1.2                DH,4096bits
2     DHE-RSA-AES256-SHA256        TLSv1.2                DH,4096bits
3     ECDHE-RSA-AES256-GCM-SHA384  TLSv1.2                ECDH,P-384,384bits
4     ECDHE-RSA-AES256-SHA384      TLSv1.2                ECDH,P-384,384bits
5     DHE-RSA-AES128-GCM-SHA256    TLSv1.2                DH,4096bits
6     DHE-RSA-AES128-SHA256        TLSv1.2                DH,4096bits
7     ECDHE-RSA-AES128-GCM-SHA256  TLSv1.2                ECDH,P-384,384bits
8     ECDHE-RSA-AES128-SHA256      TLSv1.2                ECDH,P-384,384bits
9     DHE-RSA-CAMELLIA256-SHA      TLSv1,TLSv1.1,TLSv1.2  DH,4096bits
10    DHE-RSA-AES256-SHA           TLSv1,TLSv1.1,TLSv1.2  DH,4096bits
11    ECDHE-RSA-AES256-SHA         TLSv1,TLSv1.1,TLSv1.2  ECDH,P-384,384bits
12    DHE-RSA-CAMELLIA128-SHA      TLSv1,TLSv1.1,TLSv1.2  DH,4096bits
13    DHE-RSA-AES128-SHA           TLSv1,TLSv1.1,TLSv1.2  DH,4096bits
14    ECDHE-RSA-AES128-SHA         TLSv1,TLSv1.1,TLSv1.2  ECDH,P-384,384bits
15    CAMELLIA256-SHA              TLSv1,TLSv1.1,TLSv1.2
16    AES256-SHA                   TLSv1,TLSv1.1,TLSv1.2
17    CAMELLIA128-SHA              TLSv1,TLSv1.1,TLSv1.2
18    AES128-SHA                   TLSv1,TLSv1.1,TLSv1.2

Certificate: trusted, 4096 bit, sha256WithRSAEncryption signature
TLS ticket lifetime hint: 300
OCSP stapling: supported

And here are a list of options

-a | --allciphers   Test all known ciphers individually at the end.
-b | --benchmark    Activate benchmark mode.
-d | --delay        Pause for n seconds between connections
-D | --debug        Output ALL the information.
-h | --help         Shows this help text.
-j | --json         Output results in JSON format.
-o | --openssl      path/to/your/openssl binary you want to use.
-v | --verbose      Increase verbosity.

The json output is useful if you're calling this from other scripts.

Share:
3,791

Related videos on Youtube

ibustama
Author by

ibustama

Updated on September 17, 2022

Comments

  • ibustama
    ibustama over 1 year

    I migrated a project from 1.1 to 1.2, then to 1.3, all of this, flawlessly. However, when I moved the version up to 1.4, I keep getting a

    NoReverseMatch at /admin/<app_name>/<model_name>/
    Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': ''}' not found.
    

    All other admin functionality seems to work fine, but every time I try to see a list, I get this NoReverseMatch error.

    My url entry for the admin is:

    (r'^admin/', include(admin.site.urls)),
    

    Here's my traceback:

    Template error:
    In template /home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/contrib/admin/templates/admin/change_list.html, error at line 44
       Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': ''}' not found.
       34 : </script>
    
    
       35 : {% endif %}{% endif %}
    
    
       36 : {% endblock %}
    
    
       37 : 
    
    
       38 : {% block bodyclass %}change-list{% endblock %}
    
    
       39 : 
    
    
       40 : {% if not is_popup %}
    
    
       41 : {% block breadcrumbs %}
    
    
       42 : <div class="breadcrumbs">
    
    
       43 : <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
    
    
       44 : &rsaquo; <a href=" {% url 'admin:app_list' app_label=cl.opts.app_label %} ">{{ app_label|capfirst|escape }}</a>
    
    
       45 : &rsaquo; {{ cl.opts.verbose_name_plural|capfirst }}
    
    
       46 : </div>
    
    
       47 : {% endblock %}
    
    
       48 : {% endif %}
    
    
       49 : 
    
    
       50 : {% block coltype %}flex{% endblock %}
    
    
       51 : 
    
    
       52 : {% block content %}
    
    
       53 :   <div id="content-main">
    
    
       54 :     {% block object-tools %}
    
    
    Traceback:
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response
      136.                     response = response.render()
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/response.py" in render
      104.             self._set_content(self.rendered_content)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/response.py" in rendered_content
      81.         content = template.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in render
      140.             return self._render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in _render
      134.         return self.nodelist.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in render
      823.                 bit = self.render_node(node, context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/debug.py" in render_node
      74.             return node.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/loader_tags.py" in render
      123.         return compiled_parent._render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in _render
      134.         return self.nodelist.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in render
      823.                 bit = self.render_node(node, context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/debug.py" in render_node
      74.             return node.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/loader_tags.py" in render
      123.         return compiled_parent._render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in _render
      134.         return self.nodelist.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in render
      823.                 bit = self.render_node(node, context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/debug.py" in render_node
      74.             return node.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/defaulttags.py" in render
      281.                 return nodelist.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in render
      823.                 bit = self.render_node(node, context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/debug.py" in render_node
      74.             return node.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/loader_tags.py" in render
      62.             result = block.nodelist.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/base.py" in render
      823.                 bit = self.render_node(node, context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/debug.py" in render_node
      74.             return node.render(context)
    File "/home/ibustama/yalea/env-yalea/lib/python2.6/site-packages/django/template/defaulttags.py" in render
      424.                         raise e
    
    Exception Type: NoReverseMatch at /admin/auth/user/
    Exception Value: Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': ''}' not found.
    
    • Admin
      Admin over 14 years
      Maybe gnutls-cli?
    • marianobianchi
      marianobianchi almost 12 years
      It seems that you've forgot to include one app to your INSTALLED_APPS configuration. Did you follow these steps to use the admin pages?
    • ibustama
      ibustama almost 12 years
      Hi thanks, I did follow those steps. I thought that maybe I missed some new default apps on the settings file, and even checked the order. The problem remained the same. Anyways, I found the problem (and it was rather dumb), so I'll post the answer.
    • Admin
      Admin almost 9 years
      After the title change, this question really isn't asking for a software-rec. Voting to reopen.
    • Admin
      Admin almost 9 years
      @fixer1234 If it makes you happier, I've removed any occurrence of the word "tool". The core question is asking how to accomplish a specific task anyway; it's a minor rephrase and far from more open-ended "list of software" type questions.
    • Admin
      Admin almost 9 years
      @Bob: I'm ecstatic. :-) Voting to reopen.
  • Jeremy Powell
    Jeremy Powell over 14 years
    Oh yeah... for some reason I was thinking it was the other way around. Maybe I can find a pre-cobbled tool... :)
  • Jeremy Powell
    Jeremy Powell about 14 years
    This is exactly what I was looking for! Thanks a lot!
  • Jeremy Powell
    Jeremy Powell over 13 years
    This is fantastic. It's even more exactly what I was looking for.
  • Hubert Kario
    Hubert Kario almost 13 years
    openssl 1.0 needs a change: if [[ "$result" =~ "Cipher :" ]] ; then instead of if [[ "$result" =~ "Cipher is " ]] ; then I also test for SSL2 and secure renegotiation: echo -n Testing ssl2... result=$(echo -n | openssl s_client -ssl2 -connect $SERVER 2>&1) if [[ "$result" =~ "Cipher :" ]] ; then echo supported. INSECURE! else echo no support, OK fi echo -n Testing SSL secure renegotiation... echo -n "" | openssl s_client -connect $SERVER 2>&1 | grep 'Secure Renegotiation'
  • Hubert Kario
    Hubert Kario almost 13 years
    Unfortunately it does support only HTTPS on standard port, can't use it to check POP3S, IMAPS or IMAP with TLS
  • Robert
    Robert over 11 years
    There is another, very sophisticated shell script available that uses sslscan and openssl: TLSSLed
  • Steven
    Steven almost 11 years
    @HubertKario - later versions of openssl do not support the -ssl2 flag (although it is still listed in the help)
  • Giel
    Giel almost 10 years
    Is there any way to use this script on IMAP with STARTTLS? STARTTLS on SMTP seems to work, but on IMAP the script doesn't even appear to run.
  • Olivier - interfaSys
    Olivier - interfaSys over 9 years
    I've listed below another script which only requires OpenSSL called CipherScan
  • Guillaume
    Guillaume over 9 years
    Couple of things: you might be running the script in your nmap distro, rather than the one you downloaded. Check by renaming yours. Then check the "portrule" which in some versions checks for commonly used port numbers. Replace with portrule = function() \n return true \n end
  • Iszi
    Iszi about 9 years
    And while it's great for public-facing sites, you can't use it for sites on networks that are isolated from the Internet.
  • indiv
    indiv almost 9 years
    @RanPaul: You can install cygwin or msys to get the bash shell and then run this script as a bash script. I tried to write a native Windows script but there's a bug in openssl s_client that causes it to hang until a keypress, so that's not going to be possible.
  • Redi
    Redi almost 9 years
    yum install sslscan works on CentOS 6.
  • Redi
    Redi almost 9 years
    "big-SSLv3 config not supported, connection failed"
  • user5504603
    user5504603 over 8 years
    sudo dnf install sslscan on Fedora 22 as well.
  • ThorSummoner
    ThorSummoner over 8 years
    The Debian nmap package appears to include the ssl-enum-ciphers script. :+1:
  • Clint Pachl
    Clint Pachl over 8 years
    One caveat is that older scripts, which may be included in your distro/package, list ciphers in alphabetical order, not server (or client) preferred order. See the above comment from @slim
  • insaner
    insaner over 8 years
    @indiv this is awesome! I added a couple of tweaks for my usage, how can I best make those available for everyone?
  • indiv
    indiv over 8 years
    @insaner: If they're substantial, I'd say to post them in a new answer. I don't have a good answer for what to do.
  • insaner
    insaner over 8 years
    @indiv, here it is: superuser.com/a/1035879/316396
  • Xiao
    Xiao about 8 years
    brew install sslscan on OSX
  • balu
    balu almost 8 years
    sudo apt-get install sslscan on Ubuntu (12.04 – so all later versions should be fine).
  • balu
    balu almost 8 years
    Update: It should be noted that the official version of sslscan found in the Debian and Ubuntu repositories (currently 1.8.2 from 2009) does not support TLS v1.1 and 1.2, see bugs.launchpad.net/ubuntu/+source/sslscan/+bug/1372741. One should therefore use the version on GitHub that the OP linked to.
  • Marki
    Marki almost 8 years
    You are performing openssl ciphers -tls1.1 and openssl ciphers -tls1.2 however those params don't seem to exist... There is only -tls1 (at least on the platforms I have tried).
  • Marki
    Marki almost 8 years
    (There seem to be additional options in the form of tls1_1 and tls1_2 but they are only shown on the master version of openssl and not even in 1.0.2 ....)
  • Paul
    Paul over 7 years
    Your answer was earlier, but Clint Pachl's answer explains ssl-enum-ciphers much more comprehensively.
  • Admin
    Admin over 7 years
    Note that this script probably won't tell you if a server supports cipher suites that OpenSSL doesn't support.
  • Dipendra Pokharel
    Dipendra Pokharel over 7 years
    Note that this script probably won't tell you if a server supports cipher suites that OpenSSL doesn't support.
  • bonsaiviking
    bonsaiviking over 7 years
    In the 2 years since this answer was written, Nmap has added support for STARTTLS over FTP, NNTP, IMAP, LDAP, POP3, PostgreSQL, SMTP, XMPP, VNC, and MS SQL, as well as many other improvements beyond simply listing supported ciphers.
  • John Yeary
    John Yeary over 6 years
    The suggestion from @Robert for TLSSLed was fantastic. It has been updated to 1.3 and has a lot more functionality. I have been using for security testing and must say that I am impressed.
  • eel ghEEz
    eel ghEEz over 5 years
  • eel ghEEz
    eel ghEEz over 5 years
    Sorry but Nmap's ssl cipher enum script shows some ciphers which openssl can't proceed with when connecting to imap.mail.yahoo.com:993.
  • Clint Pachl
    Clint Pachl over 5 years
    @eelghEEz Works fine on OpenBSD 6.4 running nmap-7.70 compiled with openssl-2.8.2 (which is LibreSSL 2.8.2 on OpenBSD). Check nmap -V on your system. Maybe you have old libraries or disabled ciphers. To check the Yahoo IMAP server, skip host discovery with the -Pn option.
  • eel ghEEz
    eel ghEEz over 5 years
    @ClintPachl The nmap script shows ciphers such as TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA but running openssl s_client -cipher EDH-RSA-DES-CBC3-SHA -connect imap.mail.yahoo.com:993 -no_ign_eof < /dev/null ; echo $? shows sslv3 alert handshake failure. Using openssl shows only 12 ciphers allowed by Yahoo IMAP on port 993: gist.github.com/ilatypov/488b4f35990a003052e422b4c108608f
  • rakpan
    rakpan about 5 years
    A word of caution.. This could cause poorly written applications to crash. Read this document before you proceed using this tool nmap.org/book/legal-issues.html
  • garethTheRed
    garethTheRed almost 5 years
    The version packaged with Debian 9 uses an older OpenSSL package, but that version doesn't support SSL2 or SSL3.
  • karafior
    karafior almost 5 years
    A word of caution - this script does not work if the server expects a client side certificate.
  • Brent Bradburn
    Brent Bradburn almost 5 years
    'sslscan' seems to not work when behind a proxy.
  • Jakob
    Jakob over 4 years
    This won't work with recent OpenSSL versions that use TLS 1.3 by default, because s_client wants -ciphersuites instead of -cipher. I changed the script accordingly (with some other tweaks)
  • Zergatul
    Zergatul over 4 years
    This is great utility. nmap is just terrible for new users. It doesn't want to scan localhost, it has problems with custom ports.
  • Yan Foto
    Yan Foto over 4 years
    Caution: this script seems to be outdated, with no support for TLSv1.3!
  • FreeText
    FreeText about 4 years
    Note that it requires a FQDN; it won't test IP addresses. It seems you have to make an account for that...
  • FreeText
    FreeText about 4 years
    As of Mar 2020, the sslscan version is 1.11.5 from the Ubuntu repositories, which includes support for TLS v1.1. and 1.2, but not TLS v1.3 because it is still using OpenSSL 1.0.2n (7 Dec 2017). I believe OpenSSL added TLS 1.3 support in v1.1.1.
  • FreeText
    FreeText about 4 years
    OpenSSL 1.1.1 does include TLS 1.1, 1.2 and 1.3 support. The parameters are -tls1_1, -tls1_2 and -tls1_3. However, -tls1_2, for example, returns more than you would expect. Try from your command line: openssl ciphers -v -tls1_2
  • Muhammad Taqi
    Muhammad Taqi over 3 years
    I ran this on my two differetn sites, one returns a list of ciphers and other doesn't at all, what does it means?
  • fencekicker
    fencekicker over 3 years
    Does this nmap script really work with alternate ports? I have an HTTPS server listening on port 8000, I can connect to it using 'openssl s_client', while nmap run with '--script ssl-enum-ciphers' and '-p 8000' only gives some terse output saying the host is up, and the port to service mapping, and no cipher information.
  • Alexander
    Alexander about 3 years
    For "OpenSSL version does not support SSLv2 / SSLv3" askubuntu.com/a/1176418/769834
  • Admin
    Admin about 2 years
    nmap 7.92 supports TLSv1.3