# PKI This material differs from normal cryptography courses in that it describes real-world use cases of cryptographic standards, libraries, and tools. Cryptography research essentially aims for two fundamental goals: 1. to guide the invention of better cryptographies and 2. to fully understand the limit of prosposed cryptographies. In daily life, ubiquitus cryptographic infrastructures automatically provide users with good enough security for communication. How is research transformed into working equipments? A crude but conceptually acceptible description of the process is as follows. 1. Security experts aware of recent crpytographic research form a commitee. 2. The commitee produces a *standard* describing - the responsibility and function of each party involved, - ownership, location, and functions of assets created by parties, - communication protocols that the paritites observe, - the crpytographic algorithms used at specific steps of the communication process, - components that encapsulate all functions described above, and - the interface requirements of the components. 3. Developers implement libraries that realize components and interface requirements mandated by the *standard*. Parts of the libraries are binaries that provide a user-friendly interface; these are called tools. 5. Administrators deploy the libraries to various parts of existing computing infrastructure in conformance to the *standard*, creating a favorable cryptographic infrastructure. 6. Users play their roles according to the *standard* and enjoy the service without much hassle. One of such is [X.509](https://tools.ietf.org/html/rfc5280), which is used by TLS/SSL. In fact X.509 is quite general, as it defines a <u>p</u>ublic <u>k</u>ey <u>i</u>nfrastruture ([PKI](https://en.wikipedia.org/wiki/Public_key_infrastructure)). This model could be used for TLS/SSL, SSH, and application/service authentication. - [OpenStack wiki on PKI](https://wiki.openstack.org/wiki/PKI) - [OpenStack docs on dogtag](https://docs.openstack.org/api-guide/key-manager/dogtag_setup.html) - [SSH certificate](https://smallstep.com/blog/use-ssh-certificates/) - [Dogtag is the OSS version of RHCS](http://www.ncsa.illinois.edu/People/jbasney/pki/) ## Dogtag [Dogtag](https://www.dogtagpki.org/wiki/PKI_Main_Page) is a full-featured PKI deployment that uses the [389 directory server](https://www.dogtagpki.org/wiki/PKI_Main_Page) (389ds) as an LDAP backend. ## Openssl ### Key generation Generate RSA key ```bash openssl genrsa -out <example.key> <bits> ``` Print private key ```bash openssl rsa -in <example.key> ``` Print public key ```bash openssl rsa -in <example.key> -pubout ``` Print textual format of the key ```bash openssl rsa -in <example.key> -text ``` Print textual format of the key (without private key) ```bash openssl rsa -in <example.key> -text -noout ``` Generate RSA key encrypt with AES256 ```bash openssl genrsa -aes256 -out <example.key> <bits> ``` Check RSA key ```bash openssl rsa -check -in <example.key> ``` Add passphrase and encrypt the key with AES256 ```bash openssl rsa -aes256 -in <example.key> -out <encrypted.key> ``` Remove passphrase from the key ```bash openssl rsa -in <example.key> -out <example.key> ``` ### Certificate signing request (CSR) Create a CSR from scratch (with passphrase) ```bash openssl req -newkey rsa:<bits> -keyout <example.key > -out <example.csr> ``` Create a CSR from scratch (without passphrase) ```bash openssl req -nodes -newkey rsa:<bits> -keyout <example.key> -out <example.csr> ``` Provide CSR subject info through the command line ```bash openssl req [-nodes] -newkey rsa:<bits> -subj "/C=<country>/ST=<state>/L=<Locality>/O=<Organization>/OU=<Organization Unit>/CN=<Common Name>" -keyout <example.key> -out <example.csr> ``` Create a CSR from existing private key. ```bash openssl req -new -key <example.key> -out <example.csr> -[digest] ``` Create a CSR from existing certificate and private key ```bash openssl x509 -x509toreq -in cert.pem -out example.csr -signkey example.key ``` Print CSR ```bash openssl req -in <example.csr> ``` Print CSR in textual format ```bash openssl req -in <example.csr> -noout -text ``` ### X.509 Certificate Create an X.509 certificate from scratch ```bash openssl req -x509 [-nodes] -newkey rsa:<bits> -keyout <example.key> -out <example.crt> -days <days> ``` Create a self signed X.509 certificate with existing private key and csr ```bash openssl x509 -req -in <example.csr> -signkey <example.key> -out <example.crt> -days <days> ``` Create child certificate using root CA's certificate and private key ```bash openssl x509 -req -in <example.csr> -CA <ca.crt> -CAkey <ca.key> -set_serial <serial> -out <example.crt> -days <days> openssl x509 -req -in <example.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -out <example.crt> -days <days> ``` Print X.509 Certificate ```bash openssl x509 -in <example.csr> ``` Print X.509 Certificate in textual format ```bash openssl x509 -in <example.csr> -noout -text ``` ### Vereification Verify validity of CSR: ```bash openssl req -in example.csr -verify ``` Verify that private key matches a certificate and CSR: ```bash openssl rsa -noout -modulus -in <example.key> | sha256sum openssl x509 -noout -modulus -in <example.crt> | sha256sum openssl req -noout -modulus -in <example.csr> | sha256sum ``` Verify Certificate (root certificate & intermediate certificate chain verified) ```bash openssl verify <example.crt> ``` Verify Certificate (root certificate verified, providing intermediate certificate chain ```bash openssl verify -untrusted <intermediate-chain.pem> <example.crt> ``` Verify Certificate (providing root CA) ```bash openssl verify -CAFile <ca.crt> -untrusted intermediate-ca-chain.pem <example.crt> ``` ### Hash Verify digests ```bash openssl dgst -[hash_function] <input_file> ``` ### Connection Connect to a server using TLS: ```bash openssl s_client -connect <host>:<port> openssl s_client -connect -host <host> -port <port> ``` Show certificates when connecting to the server ```bash openssl s_client -showcerts -host <host> -port <port> < /dev/null ``` Connect to a server and verify its host name ```bash openssl s_client -verify_hostname <hostname> -connect <host>:<port> ``` Connect to a server with SNI override ```bash openssl s_client -servername <hostname> -host <host> -port <port> ``` Connect to a server providing cipher suite ```bash openssl s_client -host <host> -port <port> -cipher <cipher_suite> ``` ### Convertion between encoding Convert certificate between DER and PEM: ```bash openssl x509 -in <example.pem> -outform der -out example.der openssl x509 -in <example.der> -inform der -out example.pem ``` ## Vault [HashiCorp Vault](https://www.vaultproject.io/docs) is a PKI-capable secret manager. We can create a root CA manually, as outlined above, and make Vault an intermediate CA. The root CA keys can then be saved on a pen-drive in a physical vault. Here is a recap on creating the root CA: ```bash openssl genrsa -aes256 -out rootCA.key 4096 # You will be prompted for password. ``` - [Vault -- tutorials](https://learn.hashicorp.com/vault) - [Vault -- PKI Secrets Engines](https://www.vaultproject.io/docs/secrets/pki) - [Vault -- Build Your Own CA](https://learn.hashicorp.com/tutorials/vault/pki-engine) - [Facebook SSH certs](https://engineering.fb.com/security/scalable-and-secure-access-with-ssh/)