# OpenSSL Playground ## Certificates ##### Print Certificate ( crt file ) `openssl x509 -in stackexchangecom.crt -text -noout` ##### Print Certificate ( pem file ) `openssl x509 -in cert.pem -text -noout` ##### Print Certificate ( cer file ) `openssl x509 -inform der -in foobar.cer -noout -text` ##### Read part of Certificate ``` openssl x509 -in foobar.crt -subject -serial -noout subject=C = BM, O = foobar Limited, CN = foobar BigTime CA serial=XXXXXXXXXXXXXXXXXXXXXXXXXXX ``` ##### Print Common Name and Serial Number ``` openssl x509 -in foobar.crt -subject -serial -noout | awk -F= '{print $NF}' foobar BigTime CA XXXXXXXXXXXXXXXXXXXXXXXXXXX ``` ## Generate RSA Private Key and Certificate ##### Generate RSA Private Key and Certificate ( with Private Key encryption ) `openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365` ##### Generate RSA Private Key and Certificate ( without Private Key encryption ) `openssl req -x509 -newkey rsa:2048 -keyout key.pem -nodes -out cert.pem -days 365` ##### Create Certificate with existing Private Key `openssl req -key priv_1024.pem -new -x509 -days 365 -out domain.crt` ##### Extract Public Key from Cert as PEM file `openssl x509 -pubkey -noout -in stackexchangecom.crt > pubkey.pem` ##### Strip the Generic Header and Footer ``` awk '{if (NR!=9 && NR!=1) {print}}' pubkey.pem MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr0YDzscT5i6T2FaRsTGN CiLB8OtPXu8N9iAyuaROh/nS0kRRsN8wUMk1TmgZhPuYM6oFS377V8W2LqhLBMrP Xi7lnhvKt2DFWCyw38RrDbEsM5dzVGErmhux3F0QqcTI92zjVW61DmE7NSQLiR4y onVpTpdAaO4jSPJxn8d+4p1sIlU2JGSk8LZSWFqaROc7KtXtlWP4HahNRZtdwvL5 dIEGGNWx+7B+XVAfY1ygc/UisldkA+a3D2+3WAtXgFZRZZ/1CWFjKWJNMAI6ZBAt lbgSNgRYxdcdleIhPLCzkzWysfltfiBmsmgz6VCoFR4KgJo8Gd3MeTWojBthM10S LwIDAQAB ``` ##### Extract Public Key from Cert in Hex format ``` openssl x509 -modulus -noout < stackexchangecom.crt | sed s/Modulus=// AF4603CEC713E62E93D85691B1318D0A22C1F0EB4F5EEF0DF62032B9A44E87F9D2D24451B0DF3050C9354E681984FB9833AA054B7EFB57C5B62EA84B04CACF5E2EE59E1BCAB760C5582CB0DFC46B0DB12C33977354612B9A1BB1DC5D10A9C4C8F76CE3556EB50E613B35240B891E32A275694E974068EE2348F2719FC77EE29D6C2255362464A4F0B652585A9A44E73B2AD5ED9563F81DA84D459B5DC2F2F974810618D5B1FBB07E5D501F635CA073F522B2576403E6B70F6FB7580B57805651659FF509616329624D30023A64102D95B812360458C5D71D95E2213CB0B39335B2B1F96D7E2066B26833E950A8151E0A809A3C19DDCC7935A88C1B61335D122F ``` ##### Print public key ``` openssl rsa -inform PEM -pubin -in pubkey.pem -text -noout Public-Key: (2048 bit) Modulus: 00:af:46:03:ce:c7:13:e6:2e:93:d8:56:91:b1:31: 8d:0a:22:c1:f0:eb:4f:5e:ef:0d:f6:20:32:b9:a4: 4e:87:f9:d2:d2:44:51:b0:df:30:50:c9:35:4e:68: 19:84:fb:98:33:aa:05:4b:7e:fb:57:c5:b6:2e:a8: 4b:04:ca:cf:5e:2e:e5:9e:1b:ca:b7:60:c5:58:2c: b0:df:c4:6b:0d:b1:2c:33:97:73:54:61:2b:9a:1b: b1:dc:5d:10:a9:c4:c8:f7:6c:e3:55:6e:b5:0e:61: 3b:35:24:0b:89:1e:32:a2:75:69:4e:97:40:68:ee: 23:48:f2:71:9f:c7:7e:e2:9d:6c:22:55:36:24:64: a4:f0:b6:52:58:5a:9a:44:e7:3b:2a:d5:ed:95:63: f8:1d:a8:4d:45:9b:5d:c2:f2:f9:74:81:06:18:d5: b1:fb:b0:7e:5d:50:1f:63:5c:a0:73:f5:22:b2:57: 64:03:e6:b7:0f:6f:b7:58:0b:57:80:56:51:65:9f: f5:09:61:63:29:62:4d:30:02:3a:64:10:2d:95:b8: 12:36:04:58:c5:d7:1d:95:e2:21:3c:b0:b3:93:35: b2:b1:f9:6d:7e:20:66:b2:68:33:e9:50:a8:15:1e: 0a:80:9a:3c:19:dd:cc:79:35:a8:8c:1b:61:33:5d: 12:2f Exponent: 65537 (0x10001) ``` ## RSA ##### Encrypt ``` echo 'Hi Alice!' | openssl rsautl -encrypt -pubin -oaep -inkey public_key.pem >message.bin // The standard defines random padding with each encrypt API call // https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding // It is always padded to 256 characters, with 2048 key ``` ##### Read ciphertext as Hex ``` xxd -ps -l 256 message.bin ``` ##### Decrypt from binary ciphertext ``` openssl rsautl -decrypt -in message.bin -inkey private_key.pem -oaep ``` ##### Decrypt and put plaintext in file ``` openssl rsautl -decrypt -in message.bin -inkey private.pem -oaep > plaintext.txt ``` ## AES ##### Encrypt ``` echo "foobar" | openssl enc -aes-256-cbc -base64 -pbkdf2 enter aes-256-cbc encryption password:alice Verifying - enter aes-256-cbc encryption password:alice U2FsdGVkX1/BRGpxGcBRBc/e9C6irJI53bh90HoLzP4= ``` ##### Decrypt (AES) ``` echo "U2FsdGVkX1/BRGpxGcBRBc/e9C6irJI53bh90HoLzP4=" | openssl enc -base64 -d | openssl enc -aes-256-cbc -d -pbkdf2 enter aes-256-cbc decryption password:alice // foobar ``` ## Key Pairs ``` openssl genrsa -out private.pem 2048 // add the -des3 flag to encrypt Private Key openssl rsa -in private.pem -outform PEM -pubout -out public.pem // extract pub key ``` ##### Convert private key file to PEM file ``` openssl pkcs12 -in mycaservercert.pfx -nodes -nocerts -out mycaservercertkey.pem // you will be prompted for password ``` ##### Print EC private key & extract public key ``` openssl ec -inform PEM -in private.pem -text -noout openssl ec -in private.pem -pubout -out pubkey.pem ``` ##### Read EC public key ``` cat pubkey.pem openssl ec -inform PEM -pubin -in pubkey.pem -text -noout ``` ##### Print RSA private key & extract public key ``` openssl rsa -inform PEM -in private.pem -text -noout openssl rsa -in private.pem -pubout -out pubkey.pem ``` ## Helpers ##### Convert hex to binary `xxd -r -p message.hex message.bin` ##### Convert hex -> base64 -> binary `cat enc_message.hex | base64 --decode > enc_message.bin` ##### Convert binary -> base64 encoded data `openssl base64 -in message.bin -out b64message.txt` ##### Verify downloaded file ``` ➜ openssl dgst -sha256 openssl-1.1.1.tar.gz SHA256(openssl-1.1.1.tar.gz)= 2836875a0f89c03d0fdf483941512613a50cfb421d6fd94b9f41d7279d586a3d ➜ cat openssl-1.1.1.tar.gz.sha256 2836875a0f89c03d0fdf483941512613a50cfb421d6fd94b9f41d7279d586a3d ``` ## Nginx Self-Signed Cert Nginx needed the `Leaf's Private Key` the `Leaf's Certificate` or a `certificate chain`. Whichever choice, I always found PEM files worked better with OpenSSL. ``` QUICK KeyChain on macOS Right-click on Leaf cert Export the Certificate as a PEM file Verify you can read it: openssl x509 -noout -text -in eafCert.pem SLOW Export all Certs. cat leaf_cert.pem > cert_chain.pem cat int_ca_cert.pem >> cert_chain.pem cat root_ca_cert.pem >> cert_chain.pem ``` If you hit `Expecting: TRUSTED CERTIFICATE error`, check you actually `chained the Certificates` and NOT the `Public Keys`. Apply the new `Leaf Private Key` and `Certificate Chain`: ``` sudo nginx -s stop sudo nginx ``` This all worked fine with `Firefox` and `Safari` on macOS. But `Chrome` gave: `Error: "Subject Alternative Name Missing"`. Despite having a `trusted` Cert Chain (`Root CA`, `Int CA`), Chrome stopped the page loading. To re-generate the files required by `Nginx`, I used the same `Root CA`, `Int CA` and focused on a new `leaf` that had a `Subject Alternative Name`. I used `Keychain`. See the picture below. ##### Reference https://rietta.com/blog/2012/01/27/openssl-generating-rsa-key-from-command/ https://www.guyrutenberg.com/2009/01/01/extract-public-key-from-x509-certificate-as-hex/ https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs https://crypto.stackexchange.com/questions/42097/what-is-the-maximum-size-of-the-plaintext-message-for-rsa-oaep