Hash, sign and verify files with OpenSSL dgst
Use openssl dgst to calculate a file digest, save a binary signature, and check that a file still matches the signature. This guide uses the OpenSSL 3 command installed on the machine, currently OpenSSL 3.6.1. You need a shell, a readable input file, and a public or private key for the signing examples. The basic hashing workflow takes a few minutes; key-based signing takes longer if you need to create or obtain keys.
The route
Jump straight to the step you need, or tick off Done means at the end.
Checkpoint: know what you are checking
A digest is a fixed-length result calculated from input data. It is useful for detecting accidental or unauthorised changes when you can compare it with a trusted value, but anybody who changes a file can also calculate a new digest. A digital signature is different: it is made with a private key and checked with the matching public key. Verification shows that the data matches the signature and that the supplied public key made it, but it does not by itself prove who controls that key.
Do not use MD5 or SHA-1 for a new integrity design. They remain available for old formats and interoperability. The manpage recommends SHA-256 for new or agile applications, and that is the default digest in this OpenSSL version.
1. Hash a file with the default
Choose an existing file and run the command below. The command reads the file and prints a hexadecimal digest to standard output. It does not alter the file and does not need elevated privileges.
openssl dgst /path/to/file.iso
Typical output has the algorithm, the file name, and the digest:
SHA256(/path/to/file.iso)= 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
Check the default explicitly when a script or runbook must be clear:
openssl dgst -sha256 /path/to/file.iso
To hash standard input, omit the file name. This is useful for a pipeline, but remember that a trailing newline changes the input.
printf '%s\n' 'text to hash' | openssl dgst -sha256
2. Select an algorithm and output format
Put the digest name after a hyphen, such as -sha512 or -sha3-256. Available names depend on how OpenSSL was built and which providers are loaded, so inspect this installation rather than copying a name from another system.
openssl list -digest-algorithms
The normal result is printable hexadecimal. Use -r when another tool expects the coreutils checksum layout: the digest comes first, followed by a space and the file name, then a newline.
openssl dgst -sha256 -r /path/to/file.iso
Use -out to write the result to a file. This overwrites an existing destination, so check the path first and do not point it at the input.
test ! -e /tmp/file.iso.sha256 || { echo 'refusing to overwrite existing output' >& exit 1; }
openssl dgst -sha256 -out /tmp/file.iso.sha256 /path/to/file.iso
cat /tmp/file.iso.sha256
Use -binary when a program needs the raw digest bytes rather than text. Do not paste binary output into a terminal. This output is suitable for a pipe or a file, and od provides a safe inspection:
openssl dgst -sha256 -binary /path/to/file.iso | od -An -tx1
3. Create a file signature
Signing reads the input and the private key, then writes a binary signature. This is a security-sensitive operation: protect the private key, avoid putting its password directly in shell history, and check that the output path is correct before writing it. The key must be suitable for the selected signature algorithm. Ed25519 and Ed448 private keys are not supported by dgst -sign; use openssl pkeyutl for those keys.
openssl dgst -sha256 \
-sign /path/to/privatekey.pem \
-out /path/to/file.sig \
/path/to/file.iso
For an encrypted private key, add a password source instead of exposing the password as a command argument. For interactive use, pass: is convenient but leaves the secret visible to shell history and possibly process inspection. Prefer a protected file, environment-specific secret store, or another -passin method appropriate to your deployment.
openssl dgst -sha256 \
-sign /path/to/privatekey.pem \
-passin file:/path/to/protected-password-file \
-out /path/to/file.sig \
/path/to/file.iso
The signing and verification options are intended for one input file. Do not add a directory or a list of unrelated files and assume one signature covers them all.
4. Verify before trusting the result
Verification needs the same digest choice, the public key, the signature, and the original file. A successful command prints Verified OK and exits successfully.
openssl dgst -sha256 \
-verify /path/to/publickey.pem \
-signature /path/to/file.sig \
/path/to/file.iso
Expected success:
Verified OK
A changed file, wrong key, wrong digest, or damaged signature produces verification failure. Treat any failure as untrusted input; do not work around it by trying several keys until one happens to pass. If you used -binary for the signature, keep it as-is. Hexadecimal signatures cannot be verified directly by this command. Convert a deliberately hex-encoded signature back to binary with a tool such as xxd -r, then verify the converted file.
Common traps and recovery
- Different digest: both sides must name the same algorithm. A SHA-256 digest cannot verify a SHA-512 signature.
- Wrong bytes: line endings, compression, a changed permissions archive, or an extra newline all produce different input. Hash the exact file you will transfer.
- Wrong key file: a private key signs; its matching public key verifies. A certificate is not automatically the right input for this command unless you have extracted or supplied the appropriate public-key file.
- Output collision: if a command overwrote a generated digest or signature, recreate it from the original source and trusted key. There is no undo inside OpenSSL; restore the previous file from a backup if it mattered.
- Provider differences: the algorithm list and provider configuration can differ between hosts. Record the OpenSSL version and chosen digest alongside reproducible build or release instructions.
Done means
- You calculated a SHA-256 digest for the exact file you care about.
- You chose text or binary output deliberately and checked the destination path.
- You created a signature without exposing the private-key password unnecessarily.
- You verified the signature with the matching public key and treated failure as a stop signal.