Build and Verify OpenSSL Cipher Lists Without Guesswork
You will use openssl ciphers to inspect the cipher order an OpenSSL installation can produce, filter out unauthenticated or unencrypted suites, and check the separate TLS 1.3 list. The examples were tested with OpenSSL 3.6.1 on Linux. Allow about 15 minutes if OpenSSL is already installed. This guide only displays and converts lists; it does not change a server, certificate or system configuration.
The route
Jump straight to the step you need, or tick off Done means at the end.
The command accepts a cipher list for TLS 1.2 and below, while TLS 1.3 suites are configured with a separate colon-separated option. Keeping those two naming systems distinct avoids a common source of confusing results.
1. Record the OpenSSL version
Start by checking which executable and release you are using:
$ command -v openssl
$ openssl version
OpenSSL 3.6.1 27 Jan 2026
Your output may differ. Cipher availability depends on the OpenSSL build, providers and security policy, so do not copy a list from another machine and assume it means the same thing here.
Checkpoint
Keep this version beside any cipher-list decision or support ticket. It makes later comparisons much easier.
2. See the default ordered list
Run the command with no cipher-list argument:
$ openssl ciphers
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:...
The full output is a colon-separated preference list. The first entry has the highest preference in this display. The default list is compiled into OpenSSL and combines TLS 1.3 suites with TLS 1.2 and older suites. The ellipsis above is only a shortened illustration, not text to paste.
To inspect one entry per line, use tr after the OpenSSL command:
$ openssl ciphers | tr ':' '\n' | head -5
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
3. Compare names and technical details
Use -v for protocol, key exchange, authentication, encryption and MAC details. Add -V when you also need the hexadecimal cipher-suite value:
$ openssl ciphers -V -s -tls1_3 'DEFAULT'
0x13,0x02 - TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
0x13,0x03 - TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
0x13,0x01 - TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD
The -stdname option adds the standard name before each cipher. This is useful when a configuration uses an OpenSSL spelling but a specification or another tool uses the standard spelling:
$ openssl ciphers -s -stdname 'DEFAULT' | head -3
TLS_AES_256_GCM_SHA384 - TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 - TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256 - TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD
4. Build a safer TLS 1.2-and-below list
A cipher string is processed from left to right. A plain term appends matching suites. ! permanently removes matches, - removes them while allowing a later term to add them again, and a leading + moves existing matches to the end. + inside a term means that both parts must match.
For a practical inspection, exclude suites with no authentication or no encryption, then ask OpenSSL to show only suites currently supported at its security level:
$ openssl ciphers -s -v 'ALL:!aNULL:!eNULL' | head -6
TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
The first three entries are TLS 1.3. ALL does not mean every imaginable suite: NULL encryption is outside it, and compiled-out algorithms will not appear. !aNULL is still useful when composing lower-level terms because anonymous suites can overlap with otherwise broad matches.
Security boundary
Do not weaken a production list merely to make an old client connect. Anonymous suites permit man-in-the-middle attacks, and NULL suites provide no encryption. If compatibility requires an older protocol or algorithm, document the peer, scope and removal date before changing the service configuration. This command itself makes no such change.
5. Check one protocol at a time
The protocol switches only have their filtering effect with -s. Use them to see what could be used if that protocol were negotiated:
$ openssl ciphers -s -tls1_2 'DEFAULT' | tr ':' '\n' | head -5
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305
This is a capability report, not a protocol-version switch. A cipher string containing TLSv1.2 also selects suites by their minimum version; it does not force a connection to use TLS 1.2.
6. Handle TLS 1.3 names separately
Pass TLS 1.3 names through -ciphersuites. Combine that list with a normal cipher string when you need both generations:
$ openssl ciphers -s \
-ciphersuites 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256' \
'ECDHE+AESGCM:!aNULL:!eNULL' | tr ':' '\n'
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
Do not put a TLS 1.3 name into the ordinary cipher string and infer success from a non-empty result. Use -ciphersuites for TLS 1.3 and verify the resulting output.
7. Convert a standard name when a tool disagrees
OpenSSL can convert a standard cipher name to its OpenSSL name:
$ openssl ciphers -convert TLS_AES_128_GCM_SHA256
OpenSSL cipher name: TLS_AES_128_GCM_SHA256
A conversion failure means this build does not recognise the supplied name. Check spelling and protocol generation before changing a service configuration.
Done means
- You recorded the local OpenSSL version and checked the actual executable.
- You can read the colon-separated order and inspect entries with
-vor-V. - You used
-swhen you needed suites compatible with the current security and protocol limits. - You excluded
aNULLandeNULLdeliberately, rather than relying on a broad name alone. - You kept TLS 1.3 in
-ciphersuitesand verified the final combined output.