Create own self signed certificate - tutorial
This tutorial learn you how create self signed certificate for develoment. In first part is certificate authority created. After import CA certificate to your system your page in browser or other applications don't show certificate error and appear as valid webpage. Next part show how create self signed certificate and use it in apache or nginx server.
Create self signed authotiry with openssl command.
Create private key with 2048 bits size for self signed certification authority [man pages]. Certificate authority private key must by protected with password. DES3 is used for encrypt of the private key. Whenever is the private key used, user will be prompted for the password.
openssl genrsa -des3 -out myCA.key 2048
DES is symmetric algorithm for the encryption.
DES3 is symmetric algorithm for the encryption which applies the DES cipher algorithm three time for each block for better security.
Generate certificate in PEM format [man pages]:
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem -subj "/C=SK/ST=Slovakia/L=Bratislava/O=organization/OU=organization unit/CN=myCA"
-x509 standard defining the format of public key certificates X.509
-nodes skip private key encription (no des).
-days validity of certificate in days (5 * 365=1825)
-sha256 digest algorithm for signature.
Convert certificate from ascii based PEM format to binnary DER format [man pages]
openssl x509 -outform der -in myCA.pem -out myCA.crt
-outform der Distinguished Encoding Rules - A binary format [X.509]
Create self signed certificate for page.
Create private key for your certificate.
openssl genrsa -out myPage.key 2048
Create certificate request. Certificate request is used when requester and authority is not some person. Requester provide csr request to authority and authority create certificate from request. This allow to requester's private key be hidden.
openssl req -new -key myPage.key -out myPage.csr -subj "/C=SK/ST=Slovakia/L=Bratislava/O=Organization/OU=Organization Unit/CN=myPage"
Create configuration ext file myPage.ext. In this file you can customize your alt_names. You can use asterisk for subdomain but not for top domain (*.dev not work) because browser block page. If you use wildcard for subdomain you don't need explicitly list domains like is in example because *.mypage.dev cover example.mypage.dev, admin.mypage.dev and db.mypage.dev, but you can.
authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = mypage.dev DNS.2 = *.mypage.dev DNS.3 = example.mypage.dev DNS.4 = admin.mypage.dev DNS.5 = db.mypage.dev
Create certificate from certificate request and subscribe certificate with myCA authority.
openssl x509 -req -in myPage.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out myPage.crt -days 1825 -sha256 -extfile myPage.ext
All commands together
All previous commands in one script. Don't forget create myPage.ext file. You don't need create myCA certificate evry time. After overwrite myCA files you must import certificate to os. For this reason after myPage.ext update run only last command for create certificate signed by myCA authority.
#!/bin/bash set -o xtrace openssl genrsa -des3 -out myCA.key 2048 openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem -subj "/C=SK/ST=Slovakia/L=Bratislava/O=organization/OU=organization unit/CN=myCA" openssl x509 -outform der -in myCA.pem -out myCA.crt openssl genrsa -out myPage.key 2048 openssl req -new -key myPage.key -out myPage.csr -subj "/C=SK/ST=Slovakia/L=Bratislava/O=Organization/OU=Organization Unit/CN=myPage" openssl x509 -req -in myPage.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out myPage.crt -days 1825 -sha256 -extfile myPage.ext read -p "done"
Example output in command line:
+ openssl genrsa -des3 -out myCA.key 2048 Generating RSA private key, 2048 bit long modulus ..........+++ .......+++ e is 65537 (0x10001) Enter pass phrase for myCA.key: Verifying - Enter pass phrase for myCA.key: + openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem -subj '/C=SK/ST=Slovakia/L=Bratislava/O=organization/OU=organization unit/CN=myCA' Enter pass phrase for myCA.key: + openssl x509 -outform der -in myCA.pem -out myCA.crt + openssl genrsa -out myPage.key 2048 Generating RSA private key, 2048 bit long modulus ..................................................................+++ ............+++ e is 65537 (0x10001) + openssl req -new -key myPage.key -out myPage.csr -subj '/C=SK/ST=Slovakia/L=Bratislava/O=Organization/OU=Organization Unit/CN=myPage' + openssl x509 -req -in myPage.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out myPage.crt -days 1825 -sha256 -extfile myPage.ext Signature ok subject=/C=SK/ST=Slovakia/L=Bratislava/O=Organization/OU=Organization Unit/CN=myPage Getting CA Private Key Enter pass phrase for myCA.key: + read -p done done
Import certificate authority to system
Import certificate in Windows 10
You can check detail of certificate with double click on myCA.crt
For certificate authority import open certificate manager certmgr.msc as administrator and import myCA.crt to "Trusted Root Certification Authorities" with mouse right click and select "All tasks/Import..."
Import certificate in Ubuntu 20
You must copy certificate in PEM format. Command dpkg-reconfigure is GUI application. You must pick up your certificate from options. Check command line output if your certificate was imported.
sudo mkdir /usr/share/ca-certificates/extra sudo cp myCA.pem /usr/share/ca-certificates/extra/myCA.crt sudo dpkg-reconfigure ca-certificates
You can use curl to validate your certificate (after web server configuration).
curl https://mypage.dev
Use certificate in http server
apache example configuration
Example use of vhost apache module. After new folder is created apache use folder automaticaly without server restart, but you must manualy update system hosts file. If you use wildcard for subdomain in your myPage.ext file you don't need update certificate. Wilcard for top domain like *.dev don't work and browser block page.
LoadModule vhost_alias_module modules/mod_vhost_alias.so LoadModule http2_module modules/mod_http2.so Protocols h2 h2c http/1.1 <VirtualHost *:80> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} </VirtualHost> <VirtualHost *:443> SSLEngine on SSLCertificateFile "/cert/myPage.crt" SSLCertificateKeyFile "/cert/myPage.key" ServerName vhosts.fqdn ServerAlias *.dev VirtualDocumentRoot "/Web/%0/public" ErrorLog logs/error_hosts.log CustomLog logs/access_hosts.log combined <Directory "/Web/"> Options Indexes FollowSymlinks MultiViews AllowOverride All Require all granted </Directory> </VirtualHost>
Now you can access to page example.mypage.dev trough folder /Web/example.mypage.dev/public/index.html
nginx example configuration
You can use nginx proxy to create https access to other applications listening on other custom port and not secured.
server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name _; ssl_certificate /cert/myPage.crt; ssl_certificate_key /cert/myPage.key; ssl on; ssl_session_cache builtin:1000 shared:SSL:10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; ssl_prefer_server_ciphers on; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_intercept_errors on; proxy_pass http://webserver:80; proxy_read_timeout 90; } }