这篇文章上次修改于 470 天前,可能其部分内容已经发生变化,如有疑问可询问作者。 Step-by-Step Based on the information above, we know that we have to: Create a private key for our own CA Create a certificate for the CA Add this certificate to the “Trusted Root Certificate Authorities” store of the clients so that it becomes trusted Create a certificate for our webserver Sign this certificate with our CA (which is trusted and therefore, also this new certificate becomes trusted) Deploy the certificate ## Using OpenSSL to create our CA Step 1: Create a private key for the CA Note: we will encrypt the key with AES because if anyone gets access to the key this person can create signed, trusted certificates. Encrypting the key adds some protection (use a 20+ password). ``` CANAME=MyOrg-RootCA # optional mkdir $CANAME cd $CANAME # generate aes encrypted private key openssl genrsa -aes256 -out $CANAME.key 4096 ``` Step 2: Create Certificate of the CA ``` # create certificate, 1826 days = 5 years # the following will ask for common name, country, ... openssl req -x509 -new -nodes -key $CANAME.key -sha256 -days 1826 -out $CANAME.crt # ... or you provide common name, country etc. via: openssl req -x509 -new -nodes -key $CANAME.key -sha256 -days 1826 -out $CANAME.crt -subj '/CN=MyOrg Root CA/C=AT/ST=Vienna/L=Vienna/O=MyOrg' ``` Step 3: Add the CA certificate to the trusted root certificates For Windows: Open the .crt file and install it for all users to “Trusted Root Certificate Authorities” (verify it by running `certmgr.msc`) if you use Intune: Go to Devices > Configuration Profiles > Create profile > Windows 10 and later, Templates, Trusted certificate > upload the .crt file For Linux (Ubuntu): ``` sudo apt install -y ca-certificates sudo cp $CANAME.crt /usr/local/share/ca-certificates sudo update-ca-certificates ``` Linux (Fedora/CentOS): ``` sudo cp $CANAME.crt /etc/pki/ca-trust/source/anchors/$CANAME.crt sudo update-ca-trust ``` Step 4: Create a certificate for the webserver ``` MYCERT=myserver openssl req -new -nodes -out $MYCERT.csr -newkey rsa:4096 -keyout $MYCERT.key -subj '/CN=My Firewall/C=AT/ST=Vienna/L=Vienna/O=MyOrg' # create a v3 ext file for SAN properties cat > $MYCERT.v3.ext << EOF basicConstraints = critical, CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always, issuer:always keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement extendedKeyUsage = critical, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = myserver.local DNS.2 = myserver1.local IP.1 = 192.168.1.1 IP.2 = 192.168.2.1 EOF ``` Note: the v3.ext file contains the properties of the v3 extension of certificates. This includes especially the SAN (subject alternative names) which contains the information about DNS or IP, which the browser needs to trust the certificate (you somehow need to make sure, that mysite.local uses the certificate that was issued for mysite.local) Step 5: Sign the certificate ``` openssl x509 -req -in $MYCERT.csr -CA $CANAME.crt -CAkey $CANAME.key -CAcreateserial -out $MYCERT.crt -days 730 -sha256 -extfile $MYCERT.v3.ext ``` Step 6: Verify the certificate ``` openssl x509 -noout -text -in $MYCERT.crt openssl verify -CAfile $CANAME.crt $MYCERT.crt ``` ## Renew self-signed certificate Step-1: Check the validity of the self-signed certificate ``` [root@controller certs]# openssl x509 -noout -text -in server.crt | grep -i -A2 validity ``` Sample Output: ![Sample Output](https://blog.37hi.com/usr/uploads/2023/08/3165602762.png) So our certificate will expire on 27 Aug 2022 Step-2: Export CSR from the expired certificate It is recommended to export the CSR as you don't have to worry about giving the same Distinguished Name information. Although this information can be collected from the certificate itself. For us, we will export the CSR from the certificate itself: ``` [root@controller certs]# openssl x509 -x509toreq -in server.crt -signkey server.key -out new-server.csr Getting request Private Key Generating certificate request ``` To check the content of CSR file: ``` [root@controller certs]# openssl req -noout -text -in new-server.csr ``` Step-3: Renew self-signed certificate Now that we have our private key and CSR, we can renew our certificate. You should not get confused with the term "renew", we are not extending the expiry of the certificate, instead we are just creating a new self signed certificate using the existing CSR and private key so the Signature Modulus is same and our application considers the certificate as same instead of new. ``` [root@controller certs]# openssl x509 -req -days 365 -in new-server.csr -signkey server.key -out new-server.crt Signature ok subject=C = IN, ST = Karnataka, L = Bangalore, O = GoLinuxCloud, OU = Admin, CN = controller.example Getting Private key ``` So, we have successfully renewed our self-signed certificate. Step-4: Verify renewed certificate ``` [root@controller certs]# sha256sum server.crt 594a31a4ee5283177e08b050e9ab919dd7f04a30aed00a87d1010de8f7048754 server.crt [root@controller certs]# sha256sum new-server.crt 39fea6346ebbc9a2d265af232561540fac0cc3ecff9f2e9e65b13731fa3228ac new-server.crt ``` So the checksum of both the certificates are different. But then what is important that Signature of both these certificate will be same which you can check as shown below. Here is the signature for `server.crt`: ``` [root@controller certs]# openssl x509 -noout -text -in server.crt Certificate: Data: Version: 1 (0x0) Serial Number: 10:c0:c6:7c:5c:95:fe:6b:dd:e6:df:b8:f4:d3:53:cd:6e:33:93:ca Signature Algorithm: sha256WithRSAEncryption Issuer: C = IN, ST = Karnataka, L = Bangalore, O = GoLinuxCloud, OU = Admin, CN = controller.example Validity Not Before: Aug 27 04:11:52 2021 GMT Not After : Aug 27 04:11:52 2022 GMT Subject: C = IN, ST = Karnataka, L = Bangalore, O = GoLinuxCloud, OU = Admin, CN = controller.example Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: 00:b4:3b:a9:e2:9b:93:7b:8b:4c:35:72:18:dd:b8: b8:09:a9:8c:8d:75:15:07:18:5a:60:17:b3:93:29: ae:5c:4c:af:5a:1b:ee:90:eb:2d:79:1d:2e:2f:54: e9:18:3d:ba:f3:fd:fc:86:66:5b:af:2f:03:b7:74: 6d:85:33:d0:b7:d2:a4:d9:23:3d:37:c5:9e:0d:0e: aa:f3:47:34:ef:44:71:ac:d2:de:86:67:c1:82:09: 96:1a:30:bf:66:20:89:d8:ef:90:5f:cc:2e:c5:16: 5f:eb:c5:1c:e3:b3:09:97:d4:5c:18:85:66:1e:40: 88:f4:47:f0:f6:78:e2:f7:df:2b:43:54:09:56:16: ca:d2:01:2c:dc:d2:46:34:50:ee:81:5b:2e:57:cc: 32:63:4b:b1:05:26:d0:73:ba:f9:2f:bb:f3:85:ac: 0e:ef:63:34:d2:5d:d2:d9:bc:81:46:42:61:f6:d6: 71:16:6d:53:41:fd:21:08:51:3b:87:d9:50:4c:54: c9:1d:f3:ca:a2:f9:67:23:58:db:85:2f:3c:01:55: 51:15:a9:e9:99:1d:2b:90:8f:1b:16:c4:fb:d5:e7: 2d:93:39:7f:2d:a2:cf:b6:b2:1e:e0:e4:b9:f4:ad: 8a:12:c6:51:43:5d:b7:d3:fd:2a:e0:98:bf:2c:e2: 9b:24:a9:68:9e:10:e2:ee:59:72:e6:b8:c0:67:c8: 9a:82:b0:7b:a1:d5:e8:84:a9:b1:7d:ef:40:fb:01: c4:7c:aa:54:8e:3c:07:82:00:db:14:ce:6d:ca:a6: 9a:98:f3:41:1c:e9:5c:69:54:80:a6:fd:af:19:74: a9:fd:cf:8d:80:0c:c7:b0:78:2b:1b:df:e5:52:d1: 84:53:8a:1e:12:5e:c8:a2:2d:ef:2d:fe:92:8b:1d: d5:d3:41:a5:47:49:94:98:5b:8f:25:9d:9f:04:47: 19:ff:3b:8a:cb:f9:10:57:e2:b5:b7:a6:b6:88:80: e4:21:5b:36:4c:f2:d6:94:99:57:d2:7e:81:d9:e8: 4e:cc:72:2a:3d:2f:72:a2:7d:2c:e1:33:d9:60:35: 17:7e:97:04:cd:1c:52:4a:1c:ef:74:9d:73:57:fe: 5d:77:44:99:f9:4b:4b:e9:1a:27:7f:2b:5c:f7:3d: b7:6b:20:e5:c0:7f:26:40:eb:80:42:43:41:f5:c3: 5e:e4:d2:96:c3:43:4b:61:0f:8a:ad:99:0a:06:8d: 84:23:cb:7c:47:9e:66:fc:dc:b1:09:80:40:6a:9b: 9d:ee:83:b9:60:94:f2:9b:fc:ec:b4:8e:60:58:5d: bf:e1:3f:97:c2:ee:6b:87:f3:e9:3a:31:60:2d:64: 5d:85:0f Exponent: 65537 (0x10001) ..... ``` Compare this with new-server.crt certificate: As you can verify, both have the same signature. ``` [root@controller certs]# openssl x509 -noout -text -in new-server.crt Certificate: Data: Version: 1 (0x0) Serial Number: 16:a4:85:9e:c1:de:6e:06:55:ac:15:6a:f4:9a:05:4e:70:04:3a:11 Signature Algorithm: sha256WithRSAEncryption Issuer: C = IN, ST = Karnataka, L = Bangalore, O = GoLinuxCloud, OU = Admin, CN = controller.example Validity Not Before: Aug 27 05:14:21 2021 GMT Not After : Aug 27 05:14:21 2022 GMT Subject: C = IN, ST = Karnataka, L = Bangalore, O = GoLinuxCloud, OU = Admin, CN = controller.example Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: 00:b4:3b:a9:e2:9b:93:7b:8b:4c:35:72:18:dd:b8: b8:09:a9:8c:8d:75:15:07:18:5a:60:17:b3:93:29: ae:5c:4c:af:5a:1b:ee:90:eb:2d:79:1d:2e:2f:54: e9:18:3d:ba:f3:fd:fc:86:66:5b:af:2f:03:b7:74: 6d:85:33:d0:b7:d2:a4:d9:23:3d:37:c5:9e:0d:0e: aa:f3:47:34:ef:44:71:ac:d2:de:86:67:c1:82:09: 96:1a:30:bf:66:20:89:d8:ef:90:5f:cc:2e:c5:16: 5f:eb:c5:1c:e3:b3:09:97:d4:5c:18:85:66:1e:40: 88:f4:47:f0:f6:78:e2:f7:df:2b:43:54:09:56:16: ca:d2:01:2c:dc:d2:46:34:50:ee:81:5b:2e:57:cc: 32:63:4b:b1:05:26:d0:73:ba:f9:2f:bb:f3:85:ac: 0e:ef:63:34:d2:5d:d2:d9:bc:81:46:42:61:f6:d6: 71:16:6d:53:41:fd:21:08:51:3b:87:d9:50:4c:54: c9:1d:f3:ca:a2:f9:67:23:58:db:85:2f:3c:01:55: 51:15:a9:e9:99:1d:2b:90:8f:1b:16:c4:fb:d5:e7: 2d:93:39:7f:2d:a2:cf:b6:b2:1e:e0:e4:b9:f4:ad: 8a:12:c6:51:43:5d:b7:d3:fd:2a:e0:98:bf:2c:e2: 9b:24:a9:68:9e:10:e2:ee:59:72:e6:b8:c0:67:c8: 9a:82:b0:7b:a1:d5:e8:84:a9:b1:7d:ef:40:fb:01: c4:7c:aa:54:8e:3c:07:82:00:db:14:ce:6d:ca:a6: 9a:98:f3:41:1c:e9:5c:69:54:80:a6:fd:af:19:74: a9:fd:cf:8d:80:0c:c7:b0:78:2b:1b:df:e5:52:d1: 84:53:8a:1e:12:5e:c8:a2:2d:ef:2d:fe:92:8b:1d: d5:d3:41:a5:47:49:94:98:5b:8f:25:9d:9f:04:47: 19:ff:3b:8a:cb:f9:10:57:e2:b5:b7:a6:b6:88:80: e4:21:5b:36:4c:f2:d6:94:99:57:d2:7e:81:d9:e8: 4e:cc:72:2a:3d:2f:72:a2:7d:2c:e1:33:d9:60:35: 17:7e:97:04:cd:1c:52:4a:1c:ef:74:9d:73:57:fe: 5d:77:44:99:f9:4b:4b:e9:1a:27:7f:2b:5c:f7:3d: b7:6b:20:e5:c0:7f:26:40:eb:80:42:43:41:f5:c3: 5e:e4:d2:96:c3:43:4b:61:0f:8a:ad:99:0a:06:8d: 84:23:cb:7c:47:9e:66:fc:dc:b1:09:80:40:6a:9b: 9d:ee:83:b9:60:94:f2:9b:fc:ec:b4:8e:60:58:5d: bf:e1:3f:97:c2:ee:6b:87:f3:e9:3a:31:60:2d:64: 5d:85:0f Exponent: 65537 (0x10001) ... ``` ## Is this a “full” certificate authority? No, it is not. A “real” Root CA usually consists of a Root CA, which signs the certificates of Intermediate CAs which then sign the certificates of websites (there could also be multiple Intermediate CAs => certificate chain). This increases the security a lot, because certificate of the Root CA is only needed in very special cases (new Intermediate CA added or gets revoked). The CA we created is only a public/private keypair, so it also does not maintain and publish Certificate Revocation List (CRL) what is usually done by CAs. A CRL a list of all revoked certificates (e.g. because the private key got leaked/compromised). If a clients receives a certificate, it will check if the certificate is still valid by checking the CRL. Besides the CRL, they should also implement the Online Certificate Status Protocol (OCSP) which is an alternative to CRLs. It also allows the client to check if a certificate is still valid or revoked, but has some advantages over CRLs. Some final comments… There are already many posts about this topic (see Further Information section), but some of them use outdated algorithms or do not contain exactly what I need. Regarding the algorithms/usage: - The private key of the Root CA should always be encrypted with a password. As stated above – if someone gets access to this key, this person is able to sign all certificates so that they become trusted. - Triple-DES (3DES) is officially being retired (by NIST) and is therefore considered as unsecure. AES was created to replace 3DES (see e.g.: https://www.cryptomathic.com/news-events/blog/3des-is-officially-being-retired) and is still considered secure. - RSA vs. Elliptic Curves: Elliptic Curves are basically preferred because of better security, higher efficiency, smaller keys and perfect forward secrecy – however, I used RSA 4096, because adoption is better (its basically available at all servers) and RSA is still unbroken. ## Further Information - OpenSSL Creating a Certificate Authority (CA): https://node-security.com/posts/openssl-creating-a-ca/ - Creating a browser trusted self-signed SSL certificate: https://medium.com/@tbusser/creating-a-browser-trusted-self-signed-ssl-certificate-2709ce43fd15 - Create Your Own SSL Certificate Authority for Local HTTPS Development: https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/ - How to Be Your Own Certificate Authority: https://www.wikihow.com/Be-Your-Own-Certificate-Authority - How to Create Trusted Self-Signed SSL Certificates and Local Domains for Testing: https://betterprogramming.pub/trusted-self-signed-certificate-and-local-domains-for-testing-7c6e6e3f9548 - OpenSSL Certificate Authority: https://jamielinux.com/docs/openssl-certificate-authority/introduction.html - OpenSSL CA keyUsage extension: https://superuser.com/questions/738612/openssl-ca-keyusage-extension
没有评论