Meta: this isn't a programming question or problem, and although there are past questions on openssl commandline the community has gotten stricter about topicality in the last few years. I don't feel strongly either way, but if the consensus is to close I will delete this.
OpenSSL (and its fork LibreSSL, which should be considered included in all my references from now on) supports both 'private key' files (which actually contain a key pair -- private and public, and must be kept private) and 'public key' files which contain only the public key (and therefore can be made public). pkeyutl
(and also legacy rsautl
) supports both of these and also (X.509v3) certificate files; a certificate contains a public key but is not the same as a public key, nor in the same format.
There are actually several variants of private key files supported by OpenSSL; the difference between them doesn't matter as long as you use OpenSSL, but may when you want to interface to or interoperate with other software. Certificate files (both PEM and DER) in particular are supported by nearly all software that does X.509-style asymmetric cryptography. (That excludes things doing PGP, SSH, Signal, etc.) Support for separate public-key files is less common, and while many things support some kind of private-key file it isn't always the same as one of OpenSSL's kinds.
All three of these file types can be in PEM format or 'DER' format. (Technically the data is ASN.1-DER encoded in both cases, but a 'DER' file is just DER, while a PEM file is PEM wrapping -- base64 with linebreaks and header/trailer lines -- around DER.) Private key files additionally can be encrypted (with a password) or not; public key and certificate files are never encrypted.
Decryption and signing require the private key and are thus limited to the key 'owner'. Encryption and verifying only need the public key, which is some systems always uses the certificate, but OpenSSL has more options.
openssl genrsa 2048 >private.pem
# writes a private key, by default in PEM, but you can specify -outform DER
# if you add a cipher option like -aes128 or -des3 it is encrypted, else not
# or
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 >private.pem
# ditto
# PS: 1024-bit RSA, although not actually broken yet, since 2014
# is not considered to provide adequate safety for most purposes
openssl rsa <private.pem -pubout >public.pem
# writes a public key file, again by default in PEM
# or
openssl pkey <private.pem -pubout >public.pem
openssl req -new -x509 -key private.pem -subj "/C=XX/ST=Utopia/O=Chaotic/CN=ReallyME" >cert.pem
# creates a self-signed certificate _containing_ (and signed by) this keypair
# with specified name, and defaults for other parameters;
# there are lots more options, see the man page or many existing Qs.
# Self-signed cert is mostly useful for test and debug, but not trusted in production;
# for a real cert you need to apply to a suitable Certificate Authority
# which is more complicated, and much more variegated, than I can fit here.
openssl pkeyutl -encrypt <data -inkey private.pem >encrypted
openssl pkeyutl -encrypt <data -pubin -inkey public.pem >encrypted
openssl pkeyutl -encrypt <data -certin -inkey cert.pem >encrypted
openssl pkeyutl -decrypt <encrypted -inkey private.pem >decrypted
openssl sha256 <data -sign private.pem >sig
# this form supports only private key file
openssl sha256 <data -verify public.pem -signature sig
openssl sha256 <data -prverify private.pem -signature sig
# and this form supports only key files but not cert
openssl sha256 <data -binary | pkeyutl -sign -inkey private.pem -pkeyopt digest:sha256 >sig
openssl sha256 <data -binary | pkeyutl -verify -inkey private.pem -pkeyopt digest:sha256 -sigfile sig
openssl sha256 <data -binary | pkeyutl -verify -pubin -inkey public.pem -pkeyopt digest:sha256 -sigfile sig
openssl sha256 <data -binary | pkeyutl -verify -certin -inkey cert.pem -pkeyopt digest:sha256 -sigfile sig
# end
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…