Map SSL/TLS cipher suites and their OpenSSL equiva

2019-07-25 16:30发布

问题:

I am trying to check which cipher suites can make a handshake with a server. I am using the script in the end of the post, which on his behalf is calling OpenSSL and the output is with the OpenSSL equvalents of the suites names.For example:

$./ciphers.sh stackoverflow.com:443
stackoverflow.com:443,SSL2(),SSL3(),TLS1(ECDHE-RSA-AES256-SHA:AES256-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA),TLS1.1(ECDHE-RSA-AES256-SHA:AES256-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA),TLS1.2(ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-SHA256:AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:AES128-SHA256:AES128-SHA)

I can't figure out how to map them with the SSL/TLS cipher suites names. What I need is a list of the cipher names, like

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 
TLS_DHE_RSA_WITH_AES_128_CBC_SHA   
TLS_RSA_WITH_AES_128_CBC_SHA       
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA 

but I just can't figure it out... Thank you for your help and time!

#!/usr/bin/env bash
ciphers2=$(openssl ciphers -ssl2 'ALL:eNULL' | sed -e 's/:/ /g')
ciphers3=$(openssl ciphers -ssl3 'ALL:eNULL' | sed -e 's/:/ /g')
cipherst1=$(openssl ciphers -tls1 'ALL:eNULL' | sed -e 's/:/ /g')
cipherst11=$(openssl ciphers -tls1.1 'ALL:eNULL' | sed -e 's/:/ /g')
cipherst12=$(openssl ciphers -tls1.2 'ALL:eNULL' | sed -e 's/:/ /g')

SSL2="SSL2("
for cipher in ${ciphers2[@]}
do
result=$(echo -n | openssl s_client -ssl2 -cipher "$cipher" -connect $1 2>&1)
if [[ "$result" =~ "Cipher is ${cipher}" ]] ; then
  SSL2="${SSL2}${cipher}:"
fi
done
SSL2=$(echo "${SSL2})" | sed -e 's/:)/)/g')

SSL3="SSL3("
for cipher in ${ciphers3[@]}
do
result=$(echo -n | openssl s_client -ssl3 -cipher "$cipher" -connect $1 2>&1)
if [[ "$result" =~ "Cipher is ${cipher}" ]] ; then
  SSL3="${SSL3}${cipher}:"
fi
done
SSL3=$(echo "${SSL3})" | sed -e 's/:)/)/g')
TLS1="TLS1("
for cipher in ${cipherst1[@]}
do
result=$(echo -n | openssl s_client -tls1 -cipher "$cipher" -connect $1 2>&1)
if [[ "$result" =~ "Cipher is ${cipher}" ]] ; then
  TLS1="${TLS1}${cipher}:"
fi
done
TLS1=$(echo "${TLS1})" | sed -e 's/:)/)/g')

TLS11="TLS1.1("
for cipher in ${cipherst11[@]}
do
result=$(echo -n | openssl s_client -tls1_1 -cipher "$cipher" -connect $1 2>&1)
if [[ "$result" =~ "Cipher is ${cipher}" ]] ; then
  TLS11="${TLS11}${cipher}:"
fi
done
TLS11=$(echo "${TLS11})" | sed -e 's/:)/)/g')

TLS12="TLS1.2("
for cipher in ${cipherst12[@]}
do
result=$(echo -n | openssl s_client -tls1_2 -cipher "$cipher" -connect $1 2>&1)
if [[ "$result" =~ "Cipher is ${cipher}" ]] ; then
  TLS12="${TLS12}${cipher}:"
fi
done
TLS12=$(echo "${TLS12})" | sed -e 's/:)/)/g')

echo "$1,$SSL2,$SSL3,$TLS1,$TLS11,$TLS12";

回答1:

NAME MAPPING: OpenSSL uses its own set of ciphersuite names which are related to, but not the same as, the names in the RFCs used by most other implementations and documentation. See the man page for ciphers on your system (if Unix-like, and bash is mostly on Unix-like systems although it can be ported to others) under the heading "CIPHER SUITE NAMES". On some systems you may need to specify a section something like man 1ssl ciphers. Or online at https://www.openssl.org/docs/man1.0.2/apps/ciphers.html (use links at the right for earlier other release if applicable, although before 1.0.1 are officially unsupported and currently 404 for me).

To manually convert an RFC name to OpenSSL: discard (leading) TLS or SSL and (embedded) WITH and change all _ to -; where the keyexchange is plain RSA (not [EC]DH[E]-RSA) discard it entirely; in some cases swap DHE to EDH (older versions only) and always swap DH_anon to ADH or ECDH_anon to AECDH; change 3DES_EDE_CBC in most cases to DES-CBC3; shorten EXPORT to EXP and move it to the beginning; drop bitlengths and CBC in some cases if not needed to disambiguate.

Note that anonymous suites have never been in included in the default list offered or accepted; export suites were removed from default starting with 1.0.0r 1.0.1m and 1.0.2a in 2015-03, and removed entirely and single-DES removed from default starting with 1.0.1s and 1.0.2g in 2016-03; 3DES RC4 SEED IDEA Camellia and DSS authentication (aka DSA) are not default in 1.1.0; SSL2 protocol has been disabled by default since 1.0.0 and is removed entirely in 1.1.0 released 2016-08; SSL3 is compiled out by default in 1.1.0 but can be added back (although you shouldn't use it, nor on lower releases, because it is broken by POODLE except for RC4 which has other flaws).

AVAILABILITY: ciphersuites fall in three classes in OpenSSL below 1.1.0: those for SSL2; those for SSL3 and up; and those for TLS1.2. SSL2 uses a different code scheme, so SSL2 suites can't be used for newer protocols or vice versa. To be pedantic, TLS1.0 dropped the Fortezza suites (which OpenSSL doesn't implement anyway) and TLS1.1 dropped the export suites, but OpenSSL still allowed them except as noted above. TLS1.2 on the other hand added a new format (AEAD) and a new PRF/KDF scheme, and with them a bunch of new ciphersuites that only work on TLS1.2; it also kept everything from TLS1.1 except single-DES and IDEA, which OpenSSL again still allowed except as above.

The -ssl2 -ssl3 -tls1 options on ciphers below 1.1.0 only limit you to suites compatible with that format, and all SSL3-up and TLS1.2 suites are compatible with both -ssl3 and -tls1; see the man page again. As @Andrew noted there were no options for -tls1.1 or -tls1.2 below 1.1.0 (edit) which adds options -tls1_1 and -tls1_2 (underscore not dot) which are still actually the same, and also adds an option -stdname to display the standard (RFC) name, avoiding the mapping issue -- but making the lines very long, IMHO unreadably so.

PS: if your goal is just to match, or pass, some audit scan that stupidly enumerates ciphers, this approach can work. If you are hoping to determine something useful about the security of a server, this is mostly a waste of time. It is enough that the server doesn't do SSL2 or SSL3 AT ALL (with any ciphersuite) and supports some decent ciphersuites and doesn't apply a bad preference (which this scan doesn't test); beyond that exactly which ciphersuites are supported matters much less to security than things like using good auth key and cert chain and maybe stapling, which this doesn't test; using good ephemeral parameters and randomness which are nearly impossible to test and this doesn't try; supporting features like 5746 and fallback and not having bugs like Heartbleed and CCS which this doesn't test; avoiding or mitigating compression issues which this doesn't test and in general may not be testable, and using record splitting as a best practice against BEAST which isn't practically testable; as well as all manner of issues above the SSL/TLS level.



标签: bash ssl openssl