Home / Alt manpages / openssl-ciphers(1ssl)

  • openssl-ciphers(1ssl)
  • OpenSSL command
  • linux

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 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 -v or -V.
  • You used -s when you needed suites compatible with the current security and protocol limits.
  • You excluded aNULL and eNULL deliberately, rather than relying on a broad name alone.
  • You kept TLS 1.3 in -ciphersuites and verified the final combined output.