An introduction on X.509
Introduction
Communication has been always a key part of our society. It allowed our ancestors to share facts, ideas and knowledge without requiring more than a common set of rules between the parts involved in the information exchange. This would allow several cultures to coordinate its actions, knowledge to be passed between generations and, in summary, the humanity to progress as they did. Although knowledge should be as open as possible, sometimes a piece of information should be kept in secret, away from peeping eyes. This secrecy problem have been around for all human history. But human cleverness has no limits. There are some historical records that help us to track down solutions to this problem to ancient Greece, where the scytale was develop. This is a device that would modify a text, substituting character by character a text until it was no longer readable. By knowing the configuration of the scytale, a reader could undo this modification of the text, and this would make the recovery of the message possible. This process is considered one of the first cypher methods, and it would lead to the develop of the cryptography, which is the study of techniques for secure communication. Even the word implies secrecy, since the radix crypto- comes from the ancient Greek kryptós (secret, hidden). Cryptography has been a useful tool that played a crucial role in several events in the human history. With the advent of the digital era, communications took a crucial role in our society. More data than ever is sent, shared and processed than ever before, and some of this data is sensitive, like bank accounts, industrial secrets or personal information. The secrecy problem is still present, and cryptography can lend us a hand here too.
Identifying the problem
Summarizing, communication is defined as the transmission of information. This process requires several parts to interact with each other, and sometimes the information transmitted should be kept secret. To achieve that, all the parts involved in the communication should be trustworthy. To illustrate the problem, we will make use of the Lasswell's model of communication:
This model differenciate 5 stages in the communication process. A bad example for this could be: a person communicates it's 4 o'clock in the morning yelling (using sound) to a neighbor to make them stop the music. In this case, there is no need to keep secrecy, but if the message contains private information some precautions should be taken. Let's suppose that we want to contact with our bank to check our funds. This information should be kept secret from malicious actors, and for that, the communication should be unreadable by them. The first obvious thing to protect the communications is to encrypt the message like Greeks did with their scytales, but then there is the problem of the key exchange: the key should not be encrypted at first because the bank wouldn't be able to decrypt our message at first or a pre-shared key could be used, but this would not be feasible since all clients should have a shared key that should be created offline and shared physically. Fortunately, there are other encryption algorithms that use two different keys to encrypt and decrypt a message. Those are known as asymmetric encryption algorithms. Using those systems we can exchange information with our bank safely, since the messages can only be decrypted with a piece of information that is not available to anyone but the receiver, not even the sender. Because those algorithms tend to be slower than symmetric encryption algorithms, they are used commonly to exchange symmetric keys. This idea can be seen in algorithms such as the Diffie-Hellman key exchange algorithm. With this, we can ensure that the message can be transferred securely through the medium. But the receiver might not be the one that we expect.
What is X.509
X.509 is an standard that defines the format of public key certificates, that can be used to identify peers in a communication effort. It is the technology that secures a big part of the communications on the internet by implementing what is known as a Public Key Infrastructure (PKI). It is used in SSL and TLS protocols, which powers HTTPS and is the backbone of a lot of our daily communications, and in offline applications, such as electronic signatures. Conceptually, a X.509 allows to establish a relationship between an identity and a public key through the use of a certificate. In other words, a peer can attest their identity by using that certificate. It is worth mentioning that the certificate contains the identity data, such as a hostname (for web servers), names (for organizations, individuals) or whatever is needed depending on the case, and a public key, that can be used to communicate with the peer. But then, other problems may arise, because a malicious actor might create a fake certificate, allowing them to impersonate the original recipient. A mechanism that allows a peer to validate the certificate is needed, and X.509 gives that possibility, allowing certificates to be signed by trustworthy third parties. And here, another concept present in X.509 appears, a Certificate Authority (CA). A Certificate Authority is an entity that is trusted by the users, and they are able to attest that other certificates are valid. Users trust those Certificate Authorities to be a truth source, and they consider certificates signed by CAs as valid. This allows to create a chain of trust with a real source. Certificate Authorities have two roles in the Public Key Infrastructure: generate valid certificates with identities for their clients and users, and negotiate with users and software vendors of their trustworthiness, making them to include their root certificates as valid sources of truth. Having the truth among vendors and users discourages Certificate Authorities to create malicious certificates, since that would lead to a trust loss, which would render the Certificate Authority as useless. If the CA is a business, it might lead even to bankruptcy, since their operations are based on the trust they give to users and clients.
X.509 in our daily lives
As it was previously stated before, X.509 powers all HTTPS communications, and it can be seen since we connect to almost every page on the internet. If a webpage connection is encrypted, the server uses its certificate to share with the client the server identity and the public key used to encrypt the data. In some browsers, a padlock will appear near the URL bar. Usually, browsers allow the user to peek the certificate information. Let's see an example on the certificate of this webpage:
Here appear all the concepts that were introduced before: identity (mforcen.dev), the certificate chain (mforcen.dev -> R11 -> ISRG Root X11), the Certificate Authority... But let's see how to work with certificates as system administrators:
OpenSSL
OpenSSL is a toolkit that provides cryptographic utilities and libraries for other pieces of software to build their own solutions. It provides cryptographic routines to help in the implementation of SSL and TLS communications, programs to generate, manage and sign certificates and even a client to connect to servers through TLS and check the certificate data. We will take a look on using OpenSSL to manage certificates. OpenSSL includes a CLI (command line interface) that allows the user to create some of the pieces used in encrypted communications, such as certificates, keys and connections. This CLI can be called from a terminal using the following command:
$ openssl
help:
Standard commands
asn1parse ca ciphers cmp
cms crl crl2pkcs7 dgst
dhparam dsa dsaparam ec
ecparam enc engine errstr
fipsinstall gendsa genpkey genrsa
help info kdf list
mac nseq ocsp passwd
pkcs12 pkcs7 pkcs8 pkey
pkeyparam pkeyutl prime rand
rehash req rsa rsautl
s_client s_server s_time sess_id
smime speed spkac srp
storeutl ts verify version
x509
Message Digest commands (see the 'dgst' command for more details)
blake2b512 blake2s256 md4 md5
rmd160 sha1 sha224 sha256
sha3-224 sha3-256 sha3-384 sha3-512
sha384 sha512 sha512-224 sha512-256
shake128 shake256 sm3
Cipher commands (see the 'enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb
aes-256-cbc aes-256-ecb aria-128-cbc aria-128-cfb
aria-128-cfb1 aria-128-cfb8 aria-128-ctr aria-128-ecb
aria-128-ofb aria-192-cbc aria-192-cfb aria-192-cfb1
aria-192-cfb8 aria-192-ctr aria-192-ecb aria-192-ofb
aria-256-cbc aria-256-cfb aria-256-cfb1 aria-256-cfb8
aria-256-ctr aria-256-ecb aria-256-ofb base64
bf bf-cbc bf-cfb bf-ecb
bf-ofb camellia-128-cbc camellia-128-ecb camellia-192-cbc
camellia-192-ecb camellia-256-cbc camellia-256-ecb cast
cast-cbc cast5-cbc cast5-cfb cast5-ecb
cast5-ofb des des-cbc des-cfb
des-ecb des-ede des-ede-cbc des-ede-cfb
des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb
des-ede3-ofb des-ofb des3 desx
rc2 rc2-40-cbc rc2-64-cbc rc2-cbc
rc2-cfb rc2-ecb rc2-ofb rc4
rc4-40 seed seed-cbc seed-cfb
seed-ecb seed-ofb sm4-cbc sm4-cfb
sm4-ctr sm4-ecb sm4-ofb
When entered without input, the CLI will return all the possible commands that can output. It is important to note that the OpenSSL CLI has some flags that can be applied to all commands we will see. One of those examples is the -config
flag, which allows the user to pass command line arguments in a text file. This specific flag is quite useful, specially when doing batch operations and the syntax for that configuration file can be found here.
Creating a private key
For now, we will focus on commands related to the management of X.509 certificates. The first step in X.509 is creating a private key, which will be used to encrypt data back to the client and like its name indicates, it should not be shared with anyone. For that, we will choose the command genrsa
. Extra information can be retrieved from the CLI using the --help
flag:
$ openssl genrsa --help
Usage: genrsa [options] numbits
General options:
-help Display this summary
-engine val Use engine, possibly a hardware device
Input options:
-3 (deprecated) Use 3 for the E value
-F4 Use the Fermat number F4 (0x10001) for the E value
-f4 Use the Fermat number F4 (0x10001) for the E value
Output options:
-out outfile Output the key to specified file
-passout val Output file pass phrase source
-primes +int Specify number of primes
-verbose Verbose output
-traditional Use traditional format for private keys
-* Encrypt the output with any supported cipher
Random state options:
-rand val Load the given file(s) into the random number generator
-writerand outfile Write random data to the specified file
Provider options:
-provider-path val Provider load path (must be before 'provider' argument if required)
-provider val Provider to load (can be specified multiple times)
-propquery val Property query used when fetching algorithms
Parameters:
numbits Size of key in bits
Additionally, an encryption cypher algorithm can be specified to protect the key with a passphrase. More information on that here. To create an encrypted private key with a width of 4096, the following command should be issued:
$ openssl genrsa -aes256 -out cert.key 4096
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIJSCD9B1K1R4CAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBtWzW0qPFFM7fDogcsDtHYBIIE
0IqLZDo+bJ9TvoCkUTpBR1r5tQOOYRS00mf6HKg9/fZkW1WPUquHMlOsaf2/9dYe
JSo1zPCHxuxfngsXLh3tdIUhCfmL+g0YVkyRrbdjUtTMXVnI54M0doFtwTyeHKXS
QAY/CdtBo0l+SWfcfU9MBDrOlxK8fCydmh9BlMG87aK6xp0pJ4f6yTR9tGpCI+C2
67lIKeF1tH0MFZs1qdU0iUUJfef6xGZNtLaPJme5Dm1bCm0EpL5BWM6BTg0pRVfT
WMkpjRk0C0BDMy2ioxy0iJt6NMIudxtO+fFMAtzor+M8ro+L07QiKWQHq6EuQJsR
u9G/Lcocdn2WBhgPhOLzw6oFRyouFYrNWvevRGI7CCAxNvOO5wh07POArw+4DClU
oHMZ2P7J9eB/Kg69v29ROrlnG+VMdDk5nwv4B3hw09rO7O6VMm9NTm3qnn1np44D
RXZkM3Os7pSkPJoanbow6cNXIzfMZD68ZUIWYE136RksRvItvMwaapMeTEqC8MHC
T8Df9cG1xAfXaD/G3CvHCXUUbFWdm9KTSPQ4F8aaU0HakUyRMl1nUCJkeEah5VNX
Ix2eHE5EWJkb5b1+Ksz6dPk7Nlwa6ImXf2eJjeWuPzBq3h9w3CjLMOiAD6vjoWle
7fyZxU9x+AbxENBLDJing15amS8EINZ0btPCFSRSVg4JCfk7KbsMSXY/T7jPKuHz
+Tkm+mtl4zxUCBvAAU4rF/awTaFb8yE0VQ4oNg8ABwQ2a+IE+fn6i7yXTBsYH4Rb
HbU2AgD1qyTHnH/G1k9gqo7Suk+JpgWHwdtAWsCEo28YQ6MxsLHMqFk+pyl1TGJp
k/BhViAgoNpVOJLUyL/2wVXIA8Tf9Q00HVUQ38kV4Atc6SB2dWZyC7uU3ru1XpEO
IAWiLaBfK/n4HIhkG2dAJOL+sCauNwaY6ogextLNWr4FKVMvyebKx6mXiQjxCjNC
41J+9bsrjwgH7XOic2bKUhNlxYpr1U7+t3PWbTeIf39xVQg1KDbyKTmw8xI24rpQ
9Of/jJaChy2Ldj1E9BznbEZgMtwFFts56sHtMw6n6oIRuPvp+JUYQYP+MMzZf7Lk
AEbboFFNw+p5BmwpwMhU09vGvxs+0FWpPoD2cZ2/BdTWM4cUb4g0eElhRNrn+7dJ
/qUQny+gvk7v1H8am1chVqvDOypOONw9FlDiwMPsuME0XsByxeGxPrlNWEydVS48
GdP7G9pwjovlDtpVaXxEDCXpjMM86Ptqii06j7C4LUncq1vpBzZ68ms1rwIaeKXb
ElqKMEchscHP7ccLbGUsVe5LT+yHtfXp+CIdN+lsOPToUov0Y6eW+7R/HjKAD9/s
LP5dpJ60LaArajiKbO9RXe1JoG78FbG/CePyM98c6Sf+P1MUYNxhFZJc9Cw3f0E4
jOsPK9BH5R5VeYmyEPM27cy+s5O76D2zX6jQvP3rZlGAvo7IF0iDINw4KCFBAjkX
6jfnewkHwSv1sQh1lZV4K3VKcf9RCIH6N/UWq5dJUERoxO7uwpHGp6lnFvIq9bx2
FfKQbYpMjTyPATf5VH0Lvg3PDGnSoS3FgBkIH2XxdZa1m4mTHhUeNSEKYikj65i1
PLoXGQAK3sJL34douR46eHOrQzY5v0ysfZqsk3iB0YT1
-----END ENCRYPTED PRIVATE KEY-----
Create a self-signed certificate
Other configurations are possible, and sometimes having a passphrase could be an issue. For instance, some web servers might require additional configuration to work with the encrypted private key. Also, although this specific certificate uses a width of 4096, this is not the only value that can be used. Other common values are 2048 and 3072. With this key, a certificate can be created, although this certificate will not be trusted by anyone, since this is a self signed certificate, but it will help us the readers to follow the explanation. To create a self signed certificate, another OpenSSL command is used, the x509
, whose help message is:
openssl x509 --help
Usage: x509 [options]
General options:
-help Display this summary
-in infile Certificate input, or CSR input file with -req (default stdin)
-passin val Private key and cert file pass-phrase source
-new Generate a certificate from scratch
-x509toreq Output a certification request (rather than a certificate)
-req Input is a CSR file (rather than a certificate)
-copy_extensions val copy extensions when converting from CSR to x509 or vice versa
-inform format CSR input file format (DER or PEM) - default PEM
-vfyopt val CSR verification parameter in n:v form
-key val Key for signing, and to include unless using -force_pubkey
-signkey val Same as -key
-keyform PEM|DER|ENGINE Key input format (ENGINE, other values ignored)
-out outfile Output file - default stdout
-outform format Output format (DER or PEM) - default PEM
-nocert No cert output (except for requested printing)
-noout No output (except for requested printing)
Certificate printing options:
-text Print the certificate in text form
-dateopt val Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822.
-certopt val Various certificate text printing options
-fingerprint Print the certificate fingerprint
-alias Print certificate alias
-serial Print serial number value
-startdate Print the notBefore field
-enddate Print the notAfter field
-dates Print both notBefore and notAfter fields
-subject Print subject DN
-issuer Print issuer DN
-nameopt val Certificate subject/issuer name printing options
-email Print email address(es)
-hash Synonym for -subject_hash (for backward compat)
-subject_hash Print subject hash value
-subject_hash_old Print old-style (MD5) subject hash value
-issuer_hash Print issuer hash value
-issuer_hash_old Print old-style (MD5) issuer hash value
-ext val Restrict which X.509 extensions to print and/or copy
-ocspid Print OCSP hash values for the subject name and public key
-ocsp_uri Print OCSP Responder URL(s)
-purpose Print out certificate purposes
-pubkey Print the public key in PEM format
-modulus Print the RSA key modulus
Certificate checking options:
-checkend intmax Check whether cert expires in the next arg seconds
Exit 1 (failure) if so, 0 if not
-checkhost val Check certificate matches host
-checkemail val Check certificate matches email
-checkip val Check certificate matches ipaddr
Certificate output options:
-set_serial val Serial number to use, overrides -CAserial
-next_serial Increment current certificate serial number
-days int Number of days until newly generated certificate expires - default 30
-preserve_dates Preserve existing validity dates
-subj val Set or override certificate subject (and issuer)
-force_pubkey infile Place the given key in new certificate
-clrext Do not take over any extensions from the source certificate or request
-extfile infile Config file with X509V3 extensions to add
-extensions val Section of extfile to use - default: unnamed section
-sigopt val Signature parameter, in n:v form
-badsig Corrupt last byte of certificate signature (for test)
-* Any supported digest, used for signing and printing
Micro-CA options:
-CA infile Use the given CA certificate, conflicts with -key
-CAform PEM|DER CA cert format (PEM/DER/P12); has no effect
-CAkey val The corresponding CA key; default is -CA arg
-CAkeyform PEM|DER|ENGINE CA key format (ENGINE, other values ignored)
-CAserial val File that keeps track of CA-generated serial number
-CAcreateserial Create CA serial number file if it does not exist
Certificate trust output options:
-trustout Mark certificate PEM output as trusted
-setalias val Set certificate alias (nickname)
-clrtrust Clear all trusted purposes
-addtrust val Trust certificate for a given purpose
-clrreject Clears all the prohibited or rejected uses of the certificate
-addreject val Reject certificate for a given purpose
Random state options:
-rand val Load the given file(s) into the random number generator
-writerand outfile Write random data to the specified file
-engine val Use engine, possibly a hardware device
Provider options:
-provider-path val Provider load path (must be before 'provider' argument if required)
-provider val Provider to load (can be specified multiple times)
-propquery val Property query used when fetching algorithms
To create the certificate, the following command can be used:
openssl x509 -new -subj "/C=ES/ST=Murcia/L=Murcia/O=Manuel Forcen/CN=mforcen.dev/" -key out.key -out out.crt
The identity is coded in the -subj
flag, and it follows the same specification than LDAP, which is part of the X.500 standand data model. With this, a new certificate will be created, and it could be used in web servers, but this certificate is only self-signed, and it will not be trusted by clients, unless the clients add this specific certificate as a trusted one. Also, there is an extension to the X.509 standard which allows to specify alternative names that might be required for clients to trust the certificate. Those are specified with the -extfile
flag, but more on that later.
Create and sign a Certificate Signing Request
Then, how a certificate is created? Should I share my private key with a Certificate Authority to allow them to create a new certificate (foreshadow: no, don't share your private key with anyone)? Here, a new concept appears, the Certificate Signing Request (CSR), which is a file that can be sent to a CA to create a final certificate in a secure way, this is: without sharing the private key and avoiding mistakes or tampering in the certificate subject. A CSR is created in OpenSSL with the req
option:
$ openssl req --help
Usage: req [options]
General options:
-help Display this summary
-engine val Use engine, possibly a hardware device
-keygen_engine val Specify engine to be used for key generation operations
-in infile X.509 request input file (default stdin)
-inform PEM|DER Input format - DER or PEM
-verify Verify self-signature on the request
Certificate options:
-new New request
-config infile Request template file
-section val Config section to use (default "req")
-utf8 Input characters are UTF8 (default ASCII)
-nameopt val Certificate subject/issuer name printing options
-reqopt val Various request text options
-text Text form of request
-x509 Output an X.509 certificate structure instead of a cert request
-CA infile Issuer cert to use for signing a cert, implies -x509
-CAkey val Issuer private key to use with -CA; default is -CA arg
(Required by some CA's)
-subj val Set or modify subject of request or cert
-subject Print the subject of the output request or cert
-multivalue-rdn Deprecated; multi-valued RDNs support is always on.
-days +int Number of days cert is valid for
-set_serial val Serial number to use
-copy_extensions val copy extensions from request when using -x509
-addext val Additional cert extension key=value pair (may be given more than once)
-extensions val Cert extension section (override value in config file)
-reqexts val Request extension section (override value in config file)
-precert Add a poison extension to the generated cert (implies -new)
Keys and Signing options:
-key val Key for signing, and to include unless -in given
-keyform format Key file format (ENGINE, other values ignored)
-pubkey Output public key
-keyout outfile File to write private key to
-passin val Private key and certificate password source
-passout val Output file pass phrase source
-newkey val Generate new key with [<alg>:]<nbits> or <alg>[:<file>] or param:<file>
-pkeyopt val Public key options as opt:value
-sigopt val Signature parameter in n:v form
-vfyopt val Verification parameter in n:v form
-* Any supported digest
Output options:
-out outfile Output file
-outform PEM|DER Output format - DER or PEM
-batch Do not ask anything during request generation
-verbose Verbose output
-noenc Don't encrypt private keys
-nodes Don't encrypt private keys; deprecated
-noout Do not output REQ
-newhdr Output "NEW" in the header lines
-modulus RSA modulus
Random state options:
-rand val Load the given file(s) into the random number generator
-writerand outfile Write random data to the specified file
Provider options:
-provider-path val Provider load path (must be before 'provider' argument if required)
-provider val Provider to load (can be specified multiple times)
-propquery val Property query used when fetching algorithms
With this help message, a new CSR can be created with the following command:
openssl req -new -key out.key -subj '/CN=mforcen.dev/C=ES/ST=Murcia/O=Manuel Forcen/emailAddress=me@mforcen.dev'
-----BEGIN CERTIFICATE REQUEST-----
MIIEsDCCApgCAQAwazEUMBIGA1UEAwwLbWZvcmNlbi5kZXYxCzAJBgNVBAYTAkVT
MQ8wDQYDVQQIDAZNdXJjaWExFjAUBgNVBAoMDU1hbnVlbCBGb3JjZW4xHTAbBgkq
hkiG9w0BCQEWDm1lQG1mb3JjZW4uZGV2MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEAtCilnUGxe/h4kzAfcZOc74HvxAN/eS20UyqEY3aOdgCZLl1uj4ws
IAVGzoLi4k09jPVYVOBVx2Se49LNIzFO97L9xV+4qrpmFjixnpOFGlQLEvEZd3Wo
tFtdieNEXlW4L2HQ90ayC6z5VdCmO/CR230vTj9Pli1HiQ0j6tmm+7pSsI2Jqqfi
qAozzbus4db6QU1f+XXYubovB5gQBrkFeoDaSpaLZaH/f3WNKv6azsuUBKS6FUeK
cL3b9D8CVqUFeRxvKhoKH0yn/LEdyzxH4iDmSiaG4zplJB4g9ESBy3cCvigmnIfz
j8IBfLGMpYd0PgAwPXKGv+xBueGksjmgBZv2MYSBA/m8eSB/6iVcMu3XGukL3g9p
hU1uBYyUiHVjPM2fXn64C6eq707eQA3CtX6Ih3pKKE0RilHmvjaJiETL8PWvxmBe
HacQfrl0nuY/jhj+SG1wl1sraMiXT53G8cpfNEU7OOVZptMy++erIWKT1NZVMekU
HUzrR1ZkJxMNrDnLQcGEuDlik9rMgxv+qYqJpuqNjC33IoAF/yITDirJd0a6A6qU
3z4a/ydQZKe9snEdGqE6m326jUTiaPOJ4xE6C5vPDq9hjRMMKyD05nTU8fYHMjKY
D6DN5yR67ZDEe+zqri3Df7uCws2N9fykA19YcjOiB8IxQ6ZYUZccn8MCAwEAAaAA
MA0GCSqGSIb3DQEBCwUAA4ICAQCce6tTOBn94DeUP/zRESvOaFRLn/r5zfuJPldw
ALjfM0XbFd8Cf0x20rkGgEnDHkYHJgLAnXSm3CCnBNkaE3HwZEBlEQ/BaPj3N/BY
6hN39IpsgoM4zwxfLzDAV1AHRt3c6vnrA2cDfoS0ugaxTmlK42m35G1Z3RiMmzRw
4qui8k+GCPIjLB9F1wLhIvFn/22OJfLSfn2FvezIERUL+XIfC3k/rhhlHZPzsP1x
VtNKew/nfPR9BBDEly7dI+Wl3czMJHQcodvk+d5EME/h3zcWRlAicaML00wKi0Bw
YQkYFVGnZH05GMiT+4Mhgw9wBvyOOJfoQ9xAgyXEDi4t78IXT3Vw35i1D/cquv7M
hY/bKp+0+D72EzJMvx4htX5GUCbLt3eT3Pm5mqRDhRRDEYBLB3KR1t8en0rNfpxp
Jk70iw9XBwbpAU2J6J00ivV7ICKZpGjMCJ4X3TBONk5zXn8w+cFcqANylzyQJdAu
j7OobFcZd7dedg388kJT8Q0gigqRWtyh3K2R0eBRRL6a1AfzgBfQpuwYORYuFjMf
N+r+EwupEYPfrUhdKA496fp8uW9taK9p4V+PO4pllUX6DIds/dPhQLgRJ9BjoJDi
Z0dqSiiIpd+xBVA5im6PFI6ckY7nWJLX1QeB57/4UMfspj/EiW2aSqng91RZjUPt
xb3GPw==
-----END CERTIFICATE REQUEST-----
Note that the header is different than the one found in a certificate. Those CSR can be used to generate certificates using the x509
command, with the -req
flag:
$ openssl x509 -req -in out.csr -out out.crt
Create a certificate with another certificate as CA
And last, but not least, let's suppose that I want to be a Certificate Authority. This is useful in organizations where there is a central authority, and different units can create entities inside the organization hierarchy or system. For instance, a business might find acting as a CA useful, since a certificate can be created and installed in all the computers in the business, and the business can create their own certificates that those computers will trust. To illustrate this, let's see how to use a root certificate to generate a valid certificate:
$ openssl x509 -req -in out.csr -CA root.crt -CAkey root.key -out out.crt
This will create a certificate signed with the CA.
X.509v3 extensions
As stated before, in some cases extensions should be added in the certificate. This is done using the -extfile
flag, which will accept a file path. The file should contain something along this content:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = myaddress.org
IP.1 = 127.0.0.1