# a new key pair: PKCS#8 private key and SPKI public keyopenssl genpkey -algorithm ed25519 -out ed25519.pemopenssl pkey -in ed25519.pem -pubout -out ed25519.pub.pem# -rawin: Ed25519 signs the message itself, there is no separate digest stepopenssl pkeyutl -sign -inkey key.pem -rawin -in message.txt -out sig.binod -An -v -tx1 sig.bin | tr -d ' \n'; echo # 64 bytes, the same on every runopenssl pkeyutl -verify -pubin -inkey pub.pem -rawin -in message.txt -sigfile sig.bin# "Signature Verified Successfully" (exit 0) or "Signature Verification Failure" (exit 1)How it works
genpkey -algorithm ed25519writes a PKCS#8BEGIN PRIVATE KEY;pkey -puboutderives the SPKIBEGIN PUBLIC KEYfrom it.pkeyutl -sign -rawinsigns the file contents as they are.-rawinis required before OpenSSL 3.5 and implied from 3.5 on, so keeping it makes the command portable.-pubintellspkeyutl -verifythat-inkeyis a public key, and-sigfilenames the signature. The exit code is0for a valid signature and1otherwise.- The run checks the generated key, prints the same signature as every other recipe of this task, and shows a one-character change in the message failing verification.
Gotchas
- Ed25519 refuses a digest:
openssl dgst -sha256 -sign key.pemfails withExplicit digest not allowed with EdDSA operations. Without a digest,dgst -signworks on OpenSSL 3.5 but fails on 3.0 (Key type not supported for this operation);pkeyutlworks on both. - Piping the message in fails:
printf … | openssl pkeyutl -sign -rawin …stops withunable to determine file size for oneshot operation. Ed25519 is one-shot, so OpenSSL needs a regular file via-inand reads all of it into memory. - Without
-pubin,pkeyutlreads-inkeyas a private key, and a public key file fails withCould not find private key from pub.pem. - The signature file holds 64 raw bytes — not DER, not base64. Encode it (
base64,od) for systems that expect text, and decode it back before-sigfile.