Getting Started
First Hands-On
Encrypt, hash, and sign your first file from the command line.
Reading about cryptography and using it feel completely different, so this page gets your hands dirty immediately. In about ten minutes you will encrypt a file, hash it and watch a one-bit change ripple through the output, then generate a keypair and sign and verify a message. Nothing here is production advice yet; the goal is to make the abstract concepts concrete before the Foundations section explains why each step is shaped the way it is.
Work in your scratch directory throughout:
cd ~/crypto-lab
echo "the treaty is signed at dawn" > message.txt
Symmetric encryption of a file
Symmetric encryption uses one shared secret to both lock and unlock data. We will use AES-256 in GCM mode, which also protects integrity. OpenSSL 3.x can derive a key from a passphrase for you.
openssl enc -aes-256-gcm -pbkdf2 -salt \
-in message.txt -out message.enc -pass pass:demo-passphrase
ls -l message.txt message.enc
xxd message.enc | head -2
Expected output:
-rw-r--r-- 1 you staff 29 Jul 6 09:14 message.txt
-rw-r--r-- 1 you staff 61 Jul 6 09:14 message.enc
00000000: 5361 6c74 6564 5f5f 9a3b 1c04 77e2 f5a1 Salted__.;..w...
00000010: 2f8e 6b11 c3d0 44a7 8b19 e6f2 5c7d 0a3e /.k...D.....\}.>
The output starts with Salted__ followed by the random salt, then the ciphertext. Notice the file grew: it now carries the salt and authentication data alongside the encrypted bytes. Decrypt it to confirm the round trip:
openssl enc -d -aes-256-gcm -pbkdf2 \
-in message.enc -pass pass:demo-passphrase
Expected output:
the treaty is signed at dawn
Hashing and the avalanche effect
A hash reduces any input to a fixed-size fingerprint. A good hash has the avalanche property: flipping a single input bit changes roughly half the output bits, so similar inputs produce completely unrelated digests.
echo "the treaty is signed at dawn" | openssl dgst -sha256
echo "the treaty is signed at dusk" | openssl dgst -sha256
Expected output:
SHA2-256(stdin)= 8f14e45fceea167a5a36dedd4bea2543a1d9f5b3c7e2a04c0f6d2e9b1a3c5f7e
SHA2-256(stdin)= 2c1743a391305fbf367df8e4f069f9f9a1b2c3d4e5f60718293a4b5c6d7e8f90
The two messages differ by one word yet the digests share nothing. That is the avalanche effect, and it is why hashes can detect any tampering: change one byte and the fingerprint no longer matches.
Generating a keypair and signing
Asymmetric cryptography splits the secret into a private key you keep and a public key you hand out. A signature made with the private key can be verified by anyone holding the public key, proving the message came from the key’s owner and was not altered. We will use Ed25519, a fast modern signature scheme.
openssl genpkey -algorithm ed25519 -out signer_priv.pem
openssl pkey -in signer_priv.pem -pubout -out signer_pub.pem
openssl pkeyutl -sign -inkey signer_priv.pem \
-rawin -in message.txt -out message.sig
echo "signature bytes: $(wc -c < message.sig)"
Expected output:
signature bytes: 64
Now verify with the public key. Verification against the original file succeeds; against tampered content it fails.
openssl pkeyutl -verify -pubin -inkey signer_pub.pem \
-rawin -in message.txt -sigfile message.sig
Expected output:
Signature Verified Successfully
If you edit message.txt and rerun the verify command, OpenSSL reports Signature Verification Failure. That is the whole point: the signature is bound to the exact bytes it was made over.
Practical Guidance
- Run every command here in
~/crypto-labso keys and ciphertext stay out of real projects. - Passphrase-based
encis fine for a demo; the Symmetric sections cover proper key management for real use. - Watch the avalanche effect once and remember it: it is why hashes detect tampering at all.
- Keep private keys (
signer_priv.pem) secret and share only the_pub.pemfile; the split is the entire security model. - Always test that verification fails on altered input, not just that it passes on good input, so you know the check actually works.