To install openssl run the following command from the bash shell:
sudo apt-get install opensslFor Windows machines you will need to download the binary and install. I recommend using a unix compatible terminal like mobaxterm or cygwin.
Once installed, you are ready to create your own self-signed certificate.
I am using this OpenSSL Ubuntu article as the base, but there are some modifications along the way, so I'll just explain the way I did it here. If you need further information, please visit that article.
The original article is using SHA1 but we really need to move to something else that is stronger like SHA256. If you are using SHA1 as suggested, you will be getting the Your connection is not private page in Chrome.
We will use your user profile root directory (~/ which points to /home/jchandra in my case) to do this work. If you use anything else, you might need to customize the caconfig.cnf and localhost.cnf content below.
To create your environment, run the following in bash:
cd ~/ && mkdir myCA && mkdir -p myCA/signedcerts && mkdir myCA/private && cd myCAThis will create the following directories under your user profile root folder:
| Directory | Contents |
|---|---|
~/myCA |
contains CA certificate, certificates database, generated certificates, keys, and requests |
~/myCA/signedcerts |
contains copies of each signed certificate |
~/myCA/private |
contains the private key |
To create the database, enter the following in bash:
echo '01' > serial && touch index.txtCreate caconfig.cnf using vim or nano or whatever Linux text-editor of your choice.
To create it using vim, do the following:
vim ~/myCA/caconfig.cnfTo create it using nano do the following:
nano ~/myCA/caconfig.cnfThe content should be like so:
# My sample caconfig.cnf file.
#
# Default configuration to use when one is not provided on the command line.
#
[ ca ]
default_ca = local_ca
#
#
# Default location of directories and files needed to generate certificates.
#
[ local_ca ]
dir = /home/<yourusername>/myCA #Mac change to /Users/<yourusername>/myCA
certificate = $dir/cacert.pem
database = $dir/index.txt
new_certs_dir = $dir/signedcerts
private_key = $dir/private/cakey.pem
serial = $dir/serial
#
#
# Default expiration and encryption policies for certificates
#
default_crl_days = 365
default_days = 1825
# sha1 is no longer recommended, we will be using sha256
default_md = sha256
#
policy = local_ca_policy
x509_extensions = local_ca_extensions
#
#
# Copy extensions specified in the certificate request
#
copy_extensions = copy
#
#
# Default policy to use when generating server certificates.
# The following fields must be defined in the server certificate.
#
# DO NOT CHANGE "supplied" BELOW TO ANYTHING ELSE.
# It is the correct content.
#
[ local_ca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = supplied
organizationName = supplied
organizationalUnitName = supplied
#
#
# x509 extensions to use when generating server certificates
#
[ local_ca_extensions ]
basicConstraints = CA:false
#
#
# The default root certificate generation policy
#
[ req ]
default_bits = 2048
default_keyfile = /home/<yourusername>/myCA/private/cakey.pem # again alter for MacOS if necessary
#
# sha1 is no longer recommended, we will be using sha256
default_md = sha256
#
prompt = no
distinguished_name = root_ca_distinguished_name
x509_extensions = root_ca_extensions
#
#
# Root Certificate Authority distinguished name
#
# DO CHANGE THE CONTENT OF THESE FIELDS TO MATCH
# YOUR OWN SETTINGS!
#
[ root_ca_distinguished_name ]
commonName = My Root Cert Authority
stateOrProvinceName = NSW
countryName = AU
emailAddress = [email protected]
organizationName = Coupa InvoiceSmash
organizationalUnitName = Development
#
[ root_ca_extensions ]
basicConstraints = CA:true
- In
[ local_ca ]section, make sure you replace<username>with your Ubuntu username that you created when you setup Ubuntu on Windows 10. Mine for example isdir = /home/jchandra/myCA. NOTE: DO NOT USE~/myCA. It does not work..
Similarly, change thedefault_keyfilesetting in[ req ]section to be the same. - Leave the
[ local_ca_policy ]section alone.commonName = supplied, etc. are correct and not to be overwritten. - In
[ root_ca_distinguished_name ]section, replace all values to your own settings.
- Run the following command so
opensslwill pick the settings automatically:
export OPENSSL_CONF=~/myCA/caconfig.cnf- Generate the Certificate Authority (CA) certificate:
openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 1825- Enter and retype the password you wish to use to import/export the certificate.
NOTE: Remember this password, you will need it throughout this walk-through.
Once you are done you should have the following files:
| File | Content |
|---|---|
~/myCA/cacert.pem |
CA public certificate |
~/myCA/private/cakey.pem |
CA private key |
In Windows, we will be using .crt file instead, so create one using the following command:
openssl x509 -in cacert.pem -out cacert.crtNow that you have your CA, you can create the actual self-signed SSL certificate.
But first, we need to create the configuration file for it. So again, use vim or nano, etc. to create the file. In this example, I will call mine localhost.cnf since that's the server that I am going to be using to test my development code. You can call it whatever you want. Just make sure you use the right filename in the export command later on.
Below is the content of ~/myCA/localhost.cnf:
#
# localhost.cnf
#
[ req ]
prompt = no
distinguished_name = server_distinguished_name
req_extensions = v3_req
[ server_distinguished_name ]
commonName = 192.168.1.1 # or your ip address
stateOrProvinceName = NSW
countryName = AU
emailAddress = [email protected]
organizationName = Coupa InvoiceSmash
organizationalUnitName = Development
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.0 = 192.168.1.1.xip.io # xip.io is a free dns public service that just returns the ip address in front of .xip.io
DNS.1 = 192.168.1.1.nip.io # Same as xip.io but we need an alternative for chrome
- Change the values in
[ server_distinguished_name ]section to match your own settings. - In
[ alt_names ]section, change the value forDNS.0andDNS.1to whatever you need using xip.io and nip.io
Once you created the configuration file, you need to export it:
export OPENSSL_CONF=~/myCA/localhost.cnfNow generate the certificate and key:
openssl req -newkey rsa:2048 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEMAgain, provide the password that you previously entered and wait for the command complete.
Next, run the following to create the unencrypted key file:
openssl rsa < tempkey.pem > server_key.pemAgain, provide the password that you previously entered and wait for the command to be completed.
Now switch back the export to caconfig.cnf so we can sign the new certificate request with the CA:
export OPENSSL_CONF=~/myCA/caconfig.cnfAnd sign it:
openssl ca -in tempreq.pem -out server_crt.pemAgain, provide the password that you previously entered and wait for the command to be completed and just type in Y whenever it asks you for [y/n].
Now you should have your self-signed certificate and the key.
| File | Content |
|---|---|
~/myCA/server_crt.pem |
Self signed SSL certificate |
~/myCA/server_key.pem |
Self signed SSL certificate private key |
In Windows, we mostly use .pfx and .crt files. Therefore, we need to convert the .pem file to .pfx. We'll use cat to combine server_key.pem and server_crt.pem into a file called hold.pem. Then we will do the conversion using openssl pkcs12 command as shown below. You can use whatever text you want to describe your new .pfx file in the -name parameter.
cat server_key.pem server_crt.pem > hold.pem
openssl pkcs12 -export -out localhost.pfx -in hold.pem -name "InvoiceSmash Dev Self-Signed SSL Certificate"Again, provide the password that you previously entered and wait for the command to be completed.
Now you should have the following files that we will use in the next section.
| File | Content |
|---|---|
~/myCA/localhost.pfx |
Self signed SSL certificate in PKCS#12 format |
~/myCA/cacert.crt |
CA certificate used to signed the self-signed certificate |
It seems it is forbidden to touch the Linux Subsystem from Windows side, but you can touch Windows side from Linux side, so that's what we are going to do.
To copy the files from inside Ubuntu, you need to know where you want to copy the files to on Windows side. For example, if I want to copy the files to C:\certificates folder, I'd do something like cp {localhost.pfx,cacert.crt} /mnt/c/certificates.
See this faq if you want to know more about this.
To install the CA and self-signed certificates, all you need to do is double-click the file from where you copied them into.
Once clicked, just follow the Install Certificate steps and you should be good.
For the CA Certificate (`cacert.crt), make sure you install it to Local Machine, Trusted Root Certification Authorities.
For the self-signed certificate (localhost.pfx), import it using IIS Server certificates and edit bindings for your site to use this certificate. You should access the site at 192.168.1.1.xip.io ( or your equivalent ). You will get security errors for 192.168.1.1 as it's not a valid CN
That's it. Now you can configure your application to use the new certificate. In IIS import the certiciate
- Double-click on your cacert certificate and enter your password when the keychain pops up
- Copy the cert from the login keychain that it's in to the System keychain
- Double click or right-click and "Get Info" on your certificate in System keychain
- Expand "Trust" section and select "Always Trust"
- You should be able to access 192.168.1.1.xip.io in Safari with no security errors
- Copy the cacert into icloud or another service you can access on the phone
- Download the file onto the phone and select to Install certificate
- Ignore the warning and click on install in the top right
- Go to Settings -> General -> About -> Certificate Trust Settings -> Enable full trust for root certificates for the CA
- You should be able to access 192.168.1.1.xip.io in Safari with no security errors
- Copy the cacert.cer and the webserver's .pfx onto the android device (see above on how to generate a .pfx from .pem)
- Settings -> Security -> Install From SD Card -> Navigate to the .cer file
- Name the certificate and keep it for VPN and Apps
- When you access the site at 192.168.1.1.xip.io in chrome you'll see a "Certificate requested" prompt. Tap install and navigate to the .pfx file. Enter your password for the .pfx file to install it
- Click on Allow