cipherdiff
cipherdiff copied to clipboard
diff ciphersuites between a server and a spec
cipherdiff
This tool allows you to compare the list of SSL/TLS ciphers offered by a server to a given cipher spec.
The output can identify ciphers supported by the server but not listed in the spec, ciphers listed in the spec but not supported by the server, as well as discrepancies in the cipher order of the server versus the given spec.
Please see the man page for details.
If you have questions, comments, or suggestions, please contact the author at [email protected] or at @jschauma.
Requirements
cipherdiff(1)
is written in Perl and requires
OpenSSL to be installed.
Installation
To install the command and manual page somewhere
convenient, run make install
; the Makefile defaults
to '/usr/local' but you can change the PREFIX:
$ make PREFIX=~ install
Examples
Listing ciphers in alphabetical order
To list the ciphers supported by the remote server in alphabetical (default) order:
$ cipherdiff www.yahoo.com
AES128-GCM-SHA256:AES128-SHA:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA:AES256-SHA256:DES-CBC3-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384
Note that the list of ciphers is necessarily restricted to a subset of ciphers supported by the client (i.e. openssl(1)).
Using an alternate openssl(1)
If you have a different version of openssl(1) installed, you can use that via the '-o' flag. In the following example, /tmp/openssl supports a much shorter list of ciphers:
$ cipherdiff -o /tmp/openssl www.yahoo.com
AES128-SHA:AES256-SHA:DES-CBC3-SHA
Listing ciphers in order of preference
To list the ciphers supported by the remote server in order of preference:
$ cipherdiff -p www.yahoo.com
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA
Listing ciphers not supported by the server
To list the ciphers not supported by the remote server, but available on the client side:
$ cipherdiff -u www.yahoo.com
CAMELLIA128-SHA:CAMELLIA256-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-CAMELLIA128-SHA:DHE-DSS-CAMELLIA256-SHA:DHE-DSS-SEED-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-SEED-SHA:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES128-SHA256:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-AES256-SHA384:ECDH-ECDSA-DES-CBC3-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA:ECDH-RSA-AES128-SHA256:ECDH-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA:ECDH-RSA-AES256-SHA384:ECDH-RSA-DES-CBC3-SHA:ECDH-RSA-RC4-SHA:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-RSA-RC4-SHA:EDH-DSS-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:PSK-3DES-EDE-CBC-SHA:PSK-AES128-CBC-SHA:PSK-AES256-CBC-SHA:PSK-RC4-SHA:RC4-MD5:RC4-SHA:SEED-SHA:SRP-3DES-EDE-CBC-SHA:SRP-AES-128-CBC-SHA:SRP-AES-256-CBC-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-RSA-AES-256-CBC-SHA
Comparing to a cipher spec
If you have an existing cipher spec and want to verify that the server follows it, you can pass it via the '-s' flag:
$ cat /tmp/s
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:RC4-MD5:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES256-SHA256:AES128-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA
$ cipherdiff -s $(cat /tmp/s) -p www.yahoo.com
Shared ciphers:
AES128-GCM-SHA256:AES128-SHA:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA:AES256-SHA256:DES-CBC3-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384
In input spec, but not supported by server: RC4-MD5
Supported by server, but not in input spec: ECDHE-RSA-AES128-SHA256
Input spec and server preference differ.
Input spec:
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:RC4-MD5:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES256-SHA256:AES128-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA
===
Observed preference:
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA
Since reading differences in a long cipher spec can be difficult, you can also ask cipherdiff(1) to generate unified diff(1) output, which humans may find easier to read:
$ cipherdiff -d -s $(cat /tmp/s) -p www.yahoo.com
--- given spec
+++ server
@@ -1,13 +1,13 @@
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
+ECDHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
-RC4-MD5
ECDHE-RSA-AES128-SHA
ECDHE-RSA-AES256-SHA
AES128-GCM-SHA256
AES256-GCM-SHA384
-AES256-SHA256
AES128-SHA256
+AES256-SHA256
AES128-SHA
AES256-SHA
DES-CBC3-SHA
You can also get the output marked up using terminal color escape sequences using the '-c' flag:
Ciphers missing on the server but found in the spec will be printed in blue, extra ciphers offered by the server but not found in the spec in magenta, ciphers that are deprioritized by the server compared to the spec in red, and ciphers that are preferred by the server over the spec in yellow:
Listing ciphers by protocol
When using the '-l' flag, cipherdiff(1) will print the list of supported ciphers together with protocol version. This allows you to identify which ciphersuites are supported when using each protocol:
$ cipherdiff.pl -p -l www.yahoo.com
ECDHE-RSA-AES128-GCM-SHA256: TLS1.2
ECDHE-RSA-AES256-GCM-SHA384: TLS1.2
ECDHE-RSA-AES128-SHA256: TLS1.2
ECDHE-RSA-AES256-SHA384: TLS1.2
ECDHE-RSA-AES128-SHA: TLS1 TLS1.1 TLS1.2
ECDHE-RSA-AES256-SHA: TLS1 TLS1.1 TLS1.2
AES128-GCM-SHA256: TLS1.2
AES256-GCM-SHA384: TLS1.2
AES128-SHA256: TLS1.2
AES128-SHA: TLS1 TLS1.1 TLS1.2
AES256-SHA: TLS1 TLS1.1 TLS1.2
AES256-SHA256: TLS1.2
DES-CBC3-SHA: TLS1 TLS1.1 TLS1.2
You can also generate output sorted by protocol ('-t'):
$ cipherdiff.pl -p -t www.yahoo.com
TLS1: ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA AES128-SHA AES256-SHA DES-CBC3-SHA
TLS1.1: ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA AES128-SHA AES256-SHA DES-CBC3-SHA
TLS1.2: ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA AES256-GCM-SHA384 AES128-SHA256 AES256-SHA256 AES128-SHA AES256-SHA DES-CBC3-SHA AES128-GCM-SHA256
As before, in either case the list of ciphers is sorted in order of server preference if the '-p' flag is given, or in alphabetical order if not.
NAME
cipherdiff - diff ciphersuites between a server and a spec
SYNOPSIS
cipherdiff [-Vcdhlptuv] [-D seconds] [-S sni] [-o openssl] [-s spec] server
[port]
DESCRIPTION
The cipherdiff tool will report the list of SSL and TLS ciphers supported
by the given server in colon-separated, ordered format. If an optional
spec is provided via the -s flag, then cipherdiff will also report on the
differences between what the server supports versus what the spec provides.
If no port is specified, cipherdiff will connect to port 443 on the given
server.
OPTIONS
The following options are supported by cipherdiff:
-D seconds Sleep for this many seconds in between connection attempts.
This can be useful if your defense mechanisms might otherwise
blacklist you for opening too many connections, but necessarily
slows down execution time of cipherdiff significantly.
-S sni Specify the Server Name Indication to use.
-V Print version information and exit.
-c When reporting cipher preference differences, display
mismatches in color. Ciphers missing on the server but found
in the spec will be printed in blue, extra ciphers offered by
the server but not found in the spec in magenta, ciphers that
are deprioritized by the server compared to the spec in red,
and ciphers that are preferred by the server over the spec in
yellow.
This is really only useful if the provided and observed specs
are sufficiently similar.
-d Report differences in the cipher preferences via diff(1).
In this case, the cipher spec will be organized as a line-break
separated list and differences displayed in 'unified' output.
This flag implies -p.
-h Display help and exit.
-l When listing ciphers, print one cipher name per line. This
will also display the protocol used for the cipher in question.
-o openssl Use the openssl(1) binary found in this location. If not
specified, cipherdiff will look in a conservatively set PATH of
the usual suspects. (cipherdiff will not honor your PATH
environment variable since it runs with taint checking turned
on.)
-p Perform a strict comparison to the given spec, accounting for
server preference. This is slow (O(n^2) on the number of
ciphers supported by the openssl(1) library), as numerous
connections have to be made to the server.
-s spec Diff the server's ciphersuite against the given spec.
-t When listing supported ciphers, sort output by protocol.
Implies -l.
-u List ciphers supported by the local openssl(1) command, but not
supported by the remote server.
-v Be verbose. Can be specified multiple times.
DETAILS
Numerous tools exist to identify the different cipher suites and SSL/TLS
protocols supported by a server. However, in order to verify whether a
remote server matches an exact cipher spec, one needs to iterate over all
protocols and compare them to the given list.
This process is very cumbersome, especially when attempted at any larger
scale. cipherdiff allows you to perform this task and report on the
differences in a more convenient manner. It does so by making multiple
connections using the openssl(1) s_client(1) command and observing the
cipher suite chosen by the server.
In order to be able to test support for a given cipher suite, it
necessarily must be supported by the local client (i.e. the openssl(1)
library in use). Results against the same server will thus vary depending
on which cipher suites your library supports.
Finally, when comparing a server's list of ciphers to a provided spec,
cipherdiff will generate no output if the two match and simply return an
exit status of 0.
EXAMPLES
The following examples illustrate common usage of this tool.
To merely report the cipher suites supported by www.example.com on port
1234:
$ cipherdiff www.example.com 1234
To list the cipher suites supported by www.example.com on port 443 in order
of preference:
$ cipherdiff -p www.example.com
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:...
To list the ciphers not supported by the server:
$ cipherdiff -u www.example.com
CAMELLIA128-SHA:CAMELLIA256-SHA:DHE-DSS-AES128-GCM-SHA256:...
To compare the cipher preference on the server against the one found in the
file '/tmp/s':
$ cipherdiff -s $(cat /tmp/s) -p www.example.com
...
To list the ciphers supported by the server in preference order by
protocol:
$ cipherdiff -t -p www.example.com
...
EXIT STATUS
The exit status of cipherdiff depends upon its invocation:
When comparing cipher suites (i.e. the -s flag was given), then cipherdiff
will return an exit status of 0 if no differences were found, an exit
status of 1 if any errors were encountered, and an exit status of 2 if
differences were found.
When listing cipher suites, cipherdiff exits 0 on success, and >0 if an
error occurred.
SEE ALSO
openssl(1)
HISTORY
cipherdiff was originally written by Jan Schaumann
<[email protected]> in October 2016.
BUGS
Please file bugs and feature requests by emailing the author.