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

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

Derive Repeatable Keys with OpenSSL KDF

You will produce a deterministic derived key with the installed openssl kdf command, save it as either hexadecimal text or raw bytes, and check the result without exposing it in an ordinary terminal transcript. The examples use HKDF and PBKDF2, the two useful starting points for most command-line tests. Allow about ten minutes.

You need OpenSSL and a shell. This guide uses the packaged /usr/bin/openssl 3.0.13 on this machine. The manual page is also from OpenSSL 3.0.13, while openssl found earlier on PATH may be a different installation. Keep the executable and the manual aligned when a result matters.

1. Check the executable and the package version

Start with read-only checks. They need no elevated privileges:

$ command -v openssl
/home/linuxbrew/.linuxbrew/bin/openssl
$ /usr/bin/openssl version
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
$ dpkg-query -W -f='${Package} ${Version}\n' openssl
openssl 3.0.13-0ubuntu3.15

If command -v points somewhere other than /usr/bin/openssl, do not assume its options and provider set are identical. Use the path you have checked, or put the intended installation first on PATH. The examples below use /usr/bin/openssl explicitly so that their version is clear.

Checkpoint: confirm that the command accepts a KDF name and that the output length is supplied with -keylen:

$ /usr/bin/openssl kdf -help
Usage: kdf [options] kdf_name
... 
 -keylen val         The size of the output derived key
 -binary             Output in binary format (default is hexadecimal)

2. Choose the input form and output length

A KDF combines secret or password material with algorithm parameters to produce a requested number of bytes. In this command, -kdfopt name:value passes those parameters to the selected KDF. Use printable values with key:, pass:, salt: and info:. Use the corresponding hexkey:, hexpass:, hexsalt: and hexinfo: forms when the input must be exact bytes rather than the characters in a shell word.

A salt is not a password and normally is not secret. It should be unique for the purpose and stored alongside whatever record needs to reproduce the derivation. Do not copy a real password or production key into shell history while experimenting. The examples use deliberately public values.

Security checkpoint

The command line can be recorded by shell history, process inspection and terminal logs. Use it for test vectors and controlled tooling, not as a general secret-management system. For a production password workflow, obtain the password through a design that does not place it in the process arguments.

3. Derive a ten-byte HKDF result

HKDF needs a digest, key material, salt and optional context information. This command writes hexadecimal text to standard output:

$ /usr/bin/openssl kdf -keylen 10 \
    -kdfopt digest:SHA2-256 \
    -kdfopt key:secret \
    -kdfopt salt:salt \
    -kdfopt info:label HKDF
AE:4D:0C:95:AF:6B:46:D3:2D:0A

The output represents ten bytes as twenty hexadecimal digits separated by colons, followed by a newline. Re-running the same command with the same OpenSSL implementation and parameters should give the same value. A changed key, salt, info string, digest or length gives a different result.

Checkpoint: save text output only when a text representation is what the next tool expects. The exact value above is a local verification result, not a universal constant for every OpenSSL build.

4. Derive a password-based result with PBKDF2

PBKDF2 takes a password, salt, digest and iteration count. This small iteration count keeps the example quick, but it is not a recommendation for a real password store. Select parameters with the security requirements of the application and its OpenSSL documentation:

$ /usr/bin/openssl kdf -keylen 32 \
    -kdfopt digest:SHA256 \
    -kdfopt pass:password \
    -kdfopt salt:salt \
    -kdfopt iter:2 PBKDF2
FD:BA:BE:1C:9D:34:72:00:78:56:E7:19:0D:01:E9:FE:7C:6A:D7:CB:C8:23:78:30:E7:73:76:63:4B:37:31:62

-keylen 32 requests 32 bytes, not 32 hexadecimal characters. In the default text mode, each byte takes two hex digits plus separators. If another program expects a fixed-size key, pass it the decoded bytes or use -binary directly.

5. Write output without mixing it into the terminal

Use -out for a named file. This avoids copying key material from a scrollback buffer:

$ install -m 600 /dev/null /tmp/hkdf.txt
$ /usr/bin/openssl kdf -keylen 10 \
    -kdfopt digest:SHA2-256 -kdfopt key:secret \
    -kdfopt salt:salt -kdfopt info:label \
    -out /tmp/hkdf.txt HKDF
$ wc -c < /tmp/hkdf.txt
31
$ cat /tmp/hkdf.txt
2A:C4:36:9F:52:59:96:F8:DE:13

The file is hexadecimal text, so ten derived bytes occupy 30 characters and the trailing newline makes 31. The install command is an ordinary user command when /tmp is writable. Do not use sudo merely because the data is cryptographic.

For a binary key, add -binary and inspect its size without printing it:

$ /usr/bin/openssl kdf -binary -keylen 10 \
    -kdfopt digest:SHA2-256 -kdfopt key:secret \
    -kdfopt salt:salt -kdfopt info:label \
    -out /tmp/hkdf.bin HKDF
$ wc -c < /tmp/hkdf.bin
10
$ file /tmp/hkdf.bin
/tmp/hkdf.bin: data

Destructive-action warning: -out replaces an existing destination. Use a new path while testing. If a replacement is needed, write to a temporary file, check its size and consumer compatibility, then move it over the old file in the same directory. Remove test key files when they are no longer needed, and remember that deletion may not remove copies from backups or shell logs.

6. Diagnose a mismatch or unsupported option

The KDF name controls which parameters are valid. An option that belongs to HKDF, PBKDF2 or scrypt is not automatically accepted by every other algorithm. Read the installed KDF manual and the algorithm-specific manual before transferring an example. List available digest command names with:

$ /usr/bin/openssl list -digest-commands | head

Use hexkey, hexpass, hexsalt or hexinfo when printable text is not the intended byte sequence. A common trap is changing key:abc to hexkey:abc: hexadecimal input needs two hex digits per byte, so that value is incomplete. Another trap is comparing text output with binary output. They contain the same derived bytes only after the text has been decoded.

The installed 3.0.13 manual lists TLS1-PRF, HKDF, SSKDF, PBKDF2, SSHKDF, X942KDF variants, X963KDF and SCRYPT. Availability depends on how OpenSSL was built and which providers are loaded. One TLS1-PRF example in this machine's manual does not accept its documented key: parameter with the packaged binary, so treat that family as build- and version-sensitive. Do not silently substitute HKDF for it: the algorithms are not interchangeable.

Done means

  • The OpenSSL executable and version used for the result are known.
  • -keylen is set to the required number of output bytes.
  • Printable and hexadecimal input forms have not been confused.
  • The output representation is intentional: text for a text consumer, or -binary for raw bytes.
  • Test secrets and derived files are not left in shell history, terminal logs or shared locations.
  • Any unsupported parameter has been checked against the selected KDF and the installed provider set.