Cipher String Syntax in nginx

In an nginx configuration file, you might configure a list of SSL ciphers like this

ssl_ciphers                HIGH:!aNULL:!eNULL:!LOW:!ADH:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;

What's the syntax of this cipher string? That is, I know (or think I know, correct me if I'm wrong) that this string is meant to provide a list of possible SSL ciphers, as well as provide a priority for them. What the documentation is less great at is explaining the format of this string.

Specific questions

  • Is the ! a negation? That is, does !DSS means don't use DSS? Or is !DSS the same of a cipher?

  • Are the : characters separators? That is is teh above a list of ciphers "HIGH, !aNULL, !eNULL, etc...", or does the : mean something else

  • Are HIGH and LOW the same of ciphers, or are they special meta-directives of some kind

  • Not pictured above, but I've seen strings like this AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:. Are the - characters part of the cipher name, or do they have a special meaning?

Is there a resource that explains how this string works, or is this a case where the people expected to work with the string are also expected to read the nginx source to figure out how it works?


This syntax is from OpenSSL. See CIPHER LIST FORMAT.

Further down it lists different ciphers and these meta ciphers like HIGH

Excerpt:

The cipher list consists of one or more cipher strings separated by colons. Commas or spaces are also acceptable separators but colons are normally used.

The actual cipher string can take several different forms.

It can consist of a single cipher suite such as RC4-SHA.

It can represent a list of cipher suites containing a certain algorithm, or cipher suites of a certain type. For example SHA1 represents all ciphers suites using the digest algorithm SHA1 and SSLv3 represents all SSL v3 algorithms.

Lists of cipher suites can be combined in a single cipher string using the + character. This is used as a logical and operation. For example SHA1+DES represents all cipher suites containing the SHA1 and the DES algorithms.

Each cipher string can be optionally preceded by the characters !, - or +.

If ! is used then the ciphers are permanently deleted from the list. The ciphers deleted can never reappear in the list even if they are explicitly stated.

If - is used then the ciphers are deleted from the list, but some or all of the ciphers can be added again by later options.

If + is used then the ciphers are moved to the end of the list. This option doesn't add any new ciphers it just moves matching existing ones.

...


Nginx ssl_ciphers directive is using OpenSSL cipher list format.

This cipher list is described as one or more cipher strings usually separated by colons or commas (spaces are also supported by OpenSSL but you will have to wrap the list in quotes with nginx).

A cipher string is a particular cipher suite or cipher suites grouped under a keyword.

By default OpenSSL comes with a default cipher list determined at the library compilation time and that exclude ciphers suites without encryption or authentication for obvious security purposes. It should be ALL:!aNULL:!eNULL as for OpenSSL 1.0.

For example cipher string HIGH means all the cipher suites providing encryption with keys larger than 128 bits while cipher string LOW matches cipher suites using 56 or 64 bits keys. Also, AES256-GCM-SHA384 and ECDHE-RSA-RC4-SHA are particular cipher suites.

Symbol ! means to remove the group of cipher suites or the particular cipher suite when the server exchanges supported cipher suites with the client during the handshake stage. For instance !eNULL and !aNULL means remove cipher suites not providing encryption and authentication.