B4J Tutorial [SERVER] Valid SSL certificate for localhost for your development machine

So I was intrigued that I couldn't have a valid ssl cert for localhost so what I did might be useful to someone:

--- THIS IS DONE IN LINUX ---

1. Generate a RSA-2048 key and save it to a file localCA.key. This file will be used as the key to generate the Root SSL certificate. You will be prompted for a pass phrase which you’ll need to enter each time you use this particular key to generate a certificate.
B4X:
openssl genrsa -des3 -out localCA.key 2048

2. You can use the key you generated to create a new Root SSL certificate. Save it to a file named localCA.pem. This certificate will have a validity of 1,024 days. Feel free to change it to any number of days you want.
B4X:
openssl req -x509 -new -nodes -key localCA.key -sha256 -days 1024 -out localCA.pem
You’ll also be prompted for other optional information:
B4X:
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:Random
Locality Name (eg, city) [Default City]:Random
Organization Name (eg, company) [Default Company Ltd]:Random
Organizational Unit Name (eg, section) []:Random
Common Name (eg, your name or your server's hostname) []:Local Certificate
Email Address []:example@domain.com

Now you have 2 files localCA.key, localCA.pem

3. Create a new OpenSSL configuration file localhost.csr.cnf so you can import these settings when creating a certificate instead of entering them on the command line.
B4X:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=US
ST=RandomState
L=RandomCity
O=RandomOrganization
OU=RandomOrganizationUnit
emailAddress=hello@example.com
CN = localhost

4. Create a v3.ext file in order to create a X509 v3 certificate.
B4X:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost

5. Create a certificate key for localhost using the configuration settings stored in localhost.csr.cnf. This key is stored in localhost.key
B4X:
openssl req -new -sha256 -nodes -out localhost.csr -newkey rsa:2048 -keyout localhost.key -config <( cat localhost.csr.cnf )

6. A certificate signing request is issued via the root SSL certificate we created earlier to create a domain certificate for localhost. The output is a certificate file called localhost.crt.
B4X:
openssl x509 -req -in localhost.csr -CA localCA.pem -CAkey localCA.key -CAcreateserial -out localhost.crt -days 500 -sha256 -extfile v3.ext

7. Create a PKCS#12 file:
B4X:
openssl pkcs12 -export -name localhostcert -in localhost.crt -inkey localhost.key -out localhost.p12



Now you have the following files: localCA.key, localCA.srl, localhost.csr, localhost.key, v3.ext, localCA.pem, localhost.crt, localhost.csr.cnf, localhost.p12


Now you need to copy the localCA.pem and localhost.p12 to your windows development machine and follow the steps below:

--- THIS IS DONE IN WINDOWS ---

First we will add a Certification Authority:
  1. Open Microsoft Management Console (Start --> Run --> mmc.exe);
  2. Choose File --> Add/Remove Snap-in;
  3. In the Standalone tab, choose Add;
  4. Choose the Certificates snap-in, and click Add;
  5. In the wizard, choose the Computer Account, and then choose Local Computer. Press Finish to end the wizard;
  6. Close the Add/Remove Snap-in dialog;
  7. Navigate to Certificates (Local Computer)
  8. Choose a store to import:
    1. If you have the Root CA certificate for the company that issued the certificate, choose Trusted Root Certification Authorities;
  9. Right-click the store and choose All Tasks --> Import
  10. Follow the wizard and provide the certificate file you have (localCA.pem);

After this you should see the Local Certificate in the Certificates List from Trusted Root Certification Authorities
localca.png



Next we need to generate the keystore that will be used in the B4J Server SSL Configuration.
Let's say the path to localhost.p12 is C:\localhost.p12 and the path to your java bin folder is C:\Java\bin\, start the command line with Administrator privileges and run the following command and go to C:\Java\bin:
B4X:
cd C:\Java\bin
keytool -importkeystore -srckeystore C:\localhost.p12 -srcstoretype PKCS12 -destkeystore C:\localhost.jks -srcstorepass YOUR_PASSWORD -deststorepass YOUR_PASSWORD -noprompt

This will create a file localhost.jks located at C:\localhost.jks

Now you can reference this file from B4J when starting the server.
B4X:
Private Sub ConfigureSSL (SslPort As Int)
   Dim ssl As SslConfiguration
   ssl.Initialize
   ssl.SetKeyStorePath("C:\", "localhost.jks")
   ssl.KeyStorePassword = "YOUR_PASSWORD"
   'ssl.KeyManagerPassword ="xxx" ' I don't know what this is used for.
   ssl.EnableConscryptProvider '<-----------
   srvr.SetSslConfiguration(ssl, SslPort)
End Sub

And now you get this:
secure-localhost.png


Notice I am running on port 51443.

*NOTE* If you are using FireFox then you need to import the localCA.pem there too by going to Options -> In the search box type Cert -> View Certificates -> Import the localCA.pem file. Now your localhost cert will be trusted.


Resources I followed to get it done:
1. How to get HTTPS working on your local development environment in 5 minutes (https://medium.freecodecamp.org/how...lopment-environment-in-5-minutes-7af615770eec)
2. Install a trusted root CA or self-signed certificate (https://success.outsystems.com/Supp...a_trusted_root_CA__or_self-signed_certificate)
3. How can i create keystore from an existing certificate (abc.crt) and abc.key files? (https://stackoverflow.com/questions...-existing-certificate-abc-crt-and-abc-key-fil)
4. Conscrypt and Http/2 (https://www.b4x.com/android/forum/threads/server-conscrypt-and-http-2.93040/)
 
Top