Use OpenSSL from the Shell Without Tripping on Defaults
Your openssl command may not be the OpenSSL your package manager thinks you installed, and that explains a lot of odd errors. You will build a small, repeatable workflow: identify the binary you are running, list what it supports, hash data, generate test bytes, and spot the configuration defaults that can change results. Allow about fifteen minutes.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need a shell and the
opensslpackage or an equivalent installation. - Versions. The examples use OpenSSL 3.6.1 from the command on this machine's
PATH. The Debian package record says OpenSSL 3.0.13, which is exactly why checking the executable matters. - What it will not touch. These steps are read-only except for data written where you explicitly redirect output. They do not create keys, contact a server, alter certificates or change system configuration.
Warning
Do not use these examples with private material until you have checked which executable and configuration are active.
1. Identify the executable
Start with the command your shell will actually run:
$ command -v openssl
/home/linuxbrew/.linuxbrew/bin/openssl
$ openssl version
OpenSSL 3.6.1 27 Jan 2026 (Library: OpenSSL 3.6.1 27 Jan 2026)
The path and version are part of the result. A package manager can report one installation while your PATH picks another. That is not automatically wrong, but it is a common source of confusing option support, provider paths and certificate-store behaviour.
Checkpoint
Save the output of command -v openssl and openssl version with any script or incident record.
If you also need the installed Debian package version, it is a separate query:
$ dpkg-query -W -f='${Package} ${Version}\n' openssl
openssl 3.0.13-0ubuntu3.15
Your package output can differ. Never substitute it for the version of the executable on PATH.
2. Ask the binary what it supports
OpenSSL is a dispatcher: the first argument picks a subcommand, and that subcommand owns most of the useful options. List what is there before guessing a name:
$ openssl list -digest-algorithms | sed -n '1,8p'
Legacy:
RSA-MD4 => MD4
RSA-MD5 => MD5
RSA-MDC2 => MDC2
RSA-RIPEMD160 => RIPEMD160
RSA-SHA1 => SHA1
RSA-SHA1-2 => RSA-SHA1
RSA-SHA224 => SHA224
This is capability information, not a recommendation to pick an old digest. For new integrity checks in this guide, use SHA-256. The exact list depends on the build and its providers.
For a specific subcommand, use its own help rather than the top-level help. This shows what the digest command accepts:
$ openssl help dgst
Usage: dgst [options] [file...]
Tip
Many subcommands have their own manual page, such as openssl-dgst. Use the top-level openssl(1ssl) page for dispatcher behaviour, common options and environment defaults, and the subcommand page for its data format.
3. Hash a file or a stream
Use dgst for a digest of bytes. This stream example is deterministic and safe to repeat:
$ printf '%s\n' 'dixon-openssl-check' | openssl dgst -sha256
SHA2-256(stdin)= a88d0c343c8843140ec1c9bc10b87a21264bd74da9a4dfcbe7405feb34e823b3
Checkpoint
You get the same digest. Note that the newline from printf is part of the input; drop it and the hash changes.
To hash a file, put its path after the options:
$ openssl dgst -sha256 /path/to/artifact.iso
SHA2-256(/path/to/artifact.iso)= ...
- Use a real path. The ellipsis above is explanatory, not output to copy.
- Compare the whole digest, not just the first few characters.
- Integrity is not authenticity. A digest checks whether the bytes match; it does not prove who made them. For that, use a signature and verify its trust chain separately.
4. Generate disposable random bytes
For a test token or fixture, ask for bytes and choose the output encoding explicitly:
$ openssl rand -hex 8
b1fdb74264d14640
Checkpoint
The value changes on every run, so check its shape: -hex 8 requests eight bytes and prints sixteen hexadecimal characters.
- Not a password manager. Do not mistake this for a password-management workflow.
- Keep secrets out of the trail. Do not paste generated secrets into shell history, tickets or source control.
- Skip
sudo. Most ordinary OpenSSL commands do not need it. Use elevated privileges only when the input or destination genuinely requires them. - Restrict where output lands. If a command writes a key or token, create it in a directory with deliberately restricted permissions and check the result before using it.
This guide does not generate a private key, because losing track of where sensitive output went is an avoidable failure.
5. Check configuration before debugging a surprise
Many OpenSSL commands read openssl.cnf. The manual says the default lives in the default certificate storage area, and openssl version -d reports that directory:
$ openssl version -d
OPENSSLDIR: "/home/linuxbrew/.linuxbrew/etc/openssl@3"
The environment variable OPENSSL_CONF can point at another configuration file. An empty value disables configuration loading for commands that honour it:
$ env OPENSSL_CONF='' openssl list -providers
Providers:
default
name: OpenSSL Default Provider
Warning
Do not export an unfamiliar OPENSSL_CONF globally while troubleshooting. A configuration file can load modules and influence certificate or random-number operations. Prefer a one-command assignment as above, inspect the file, and run unset OPENSSL_CONF if you set it during a test.
6. Test command availability without guessing
Here is the odd one. The top-level manual documents openssl no-XXX for checking whether a command or cipher name exists, and it works backwards from what you would expect:
- Name missing: it returns 0 (success) and prints
no-XXX. - Name present: it returns 1 and prints
XXX.
$ openssl no-definitely_missing_command
no-definitely_missing_command
$ printf 'status=%s\n' "$?"
status=0
Per the manual, it cannot detect pseudo-commands such as quit, list or no-XXX itself.
Warning
Do not use this as a generic "command succeeded" test. A printed no- prefix means the requested item is absent. For normal operations, run the real subcommand and check its output and exit status.
Done means
- Right binary. You know which OpenSSL executable and library version your shell selected.
- No guessing. You can list supported commands instead of assuming an option exists.
- Reproducible hashes. You can reproduce a SHA-256 digest while accounting for every input byte.
- Secrets and config. You treat random output as sensitive and know
OPENSSL_CONFcan change behaviour. - Diagnose first. You treat an unexpected result as a version, provider, configuration or input problem before reaching for
sudo.