I was going through the following tutorial https://www.youtube.com/watch?v=8ptiZlO7ROs to set up an HTTPS connection, and noticed that it seems the code only makes use of server.crt and server.key (I'm not sure if server.key is the public or private key in the RSA key pair). But shouldn't two keys be needed for HTTPS? (both public and private keys?).
Altogether, the tutorial covers generation of the following files:
ca.crt ca.key ca.srl client.crt client.csr client.key server.crt server.csr server.key But the node.js code only seems to make use of server.crt and server.key:
const express = require('express') const fs = require('fs') const https = require('https') const path = require('path') const app = express() const directoryToServe = 'client' const port = 3443 app.use('/', express.static(path.join(__dirname,'..',directoryToServe))) const httpsOptions = { cert: fs.readFileSync(path.join(__dirname,'ssl','server.crt')), key: fs.readFileSync(path.join(__dirname,'ssl','server.key')) } https.createServer(httpsOptions,app) .listen(port, function() { console.log(`Serving the '${directoryToServe}' directory at localhost:${port}`) }) My understanding of HTTPS is that:
- The server sends the client a public key
- The client returns a symmetric key encrypted with the public key
- the server decrypts the symmetric key using the private key
- the client and server communicate using the symmetric key
But as the code above uses only one key server.key (which I assume is the public key?), how does the HTTPS communication work since I assume both assymetric keys should be needed (public and private) to negotiate the symmetric key exchange?
Here is the code to generate the keys/certificates:
#!/bin/bash # set values for certificate DNs # note: CN is set to different values in the sections below ORG="000_Test_Certificates" # set values that the commands will share VALID_DAYS=360 CA_KEY=ca.key CA_CERT=ca.crt CLIENT_KEY=client.key CLIENT_CERT=client.crt CLIENT_CSR=client.csr CLIENT_P12=client.p12 SERVER_KEY=server.key SERVER_CERT=server.crt SERVER_CSR=server.csr KEY_BITS=2048 echo echo "Create CA certificate..." CN="Test CA" openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:$KEY_BITS -out $CA_KEY openssl req -new -x509 -days $VALID_DAYS -key $CA_KEY -subj "//CN=$CN\O=$ORG" -out $CA_CERT echo "Done." echo echo "Creating Server certificate..." CN="localhost" openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:$KEY_BITS -out $SERVER_KEY openssl req -new -key $SERVER_KEY -subj "//CN=$CN\O=$ORG" -out $SERVER_CSR openssl x509 -days $VALID_DAYS -req -in $SERVER_CSR -CAcreateserial -CA $CA_CERT -CAkey $CA_KEY -out $SERVER_CERT echo "Done." echo echo "Creating Client certificate..." CN="Test User 1" USER_ID="testuser1" P12_PASSWORD= openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:$KEY_BITS -out $CLIENT_KEY openssl req -new -key $CLIENT_KEY -subj "//CN=$CN\O=$ORG\UID=$USER_ID" -out $CLIENT_CSR openssl x509 -days $VALID_DAYS -req -in $CLIENT_CSR -CAcreateserial -CA $CA_CERT -CAkey $CA_KEY -out $CLIENT_CERT openssl pkcs12 -in $CLIENT_CERT -inkey $CLIENT_KEY -export -password pass:$P12_PASSWORD -out $CLIENT_P12 echo "Done." echo echo "----- Don't forget to open your browser and install your $CA_CERT and $CLIENT_P12 certificates -----" echo Thank you in advance!
server.keycontains the private key? I've appended the key generation code above in the OP.server.keyis the private key, and the public key is contained inserver.crt). Alternatively, if that's not the case, how would the server know where to fetch its private key? (which is really my original question)optionsparameter for thehttps.createServer()method. That says it accepts any options fromtls.createServer(),tls.createSecureContext()andhttp.createServer(). Digging a bit more, it'stls.createSecureContext()that asks for thekeyandcertparameters: nodejs.org/api/tls.html#tls_tls_createsecurecontext_options . This will answer your question definitively.