DEV Community


Posted on

Quickly create a self signed certificate for a custom domain

I often find myself needing a simple self signed certificate that is either for a wildcard domain or that cover multiple domain names. And then, even when I have openssl somewhere the questions are "do I have the config file?", "do I really need to fill in all those distinguished name values?", "where do I put additional domains", etc.

So to make my life simpler I made a small batch script that takes domain names as arguments, creates configuration file and instructs openssl to create a self signed certificate for those domains.

Example usage

Requesting certificates like:

E:\Temp> self-signed-cert mydomain.local *.mydomain.local

will generate one certificate with 2 domain names (mydomain.local and *.mydomain.local) and will produce the following files:

  1. mydomain.local.conf - configuration file for openssl
  2. mydomain.local.key - private key
  3. mydomain.local.crt - certificate
  4. mydomain.local.pfx - a pkcs#12 file with both certificate and private key

Content of the generated mydomain.local.conf file:

default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = req_distinguished_name
x509_extensions = v3_req

CN = mydomain.local

subjectAltName = @san

DNS.1 = mydomain.local
DNS.2 = *.mydomain.local

And the generated certificate looks like this:

        Version: 3 (0x2)
        Serial Number:
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = mydomain.local
            Not Before: Apr 13 12:12:57 2020 GMT
            Not After : Apr 11 12:12:57 2030 GMT
        Subject: CN = mydomain.local
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:mydomain.local, DNS:*.mydomain.local
    Signature Algorithm: sha256WithRSAEncryption

Batch file explained

if [%1]==[] (
  echo Usage: %0 ^<domain_name^> [additional_domain] [additional_domain] ...
  exit /b 1

Just making sure that there is at least one argument

if [%2]==[] (set addsan=) else (set addsan=1)

Checking if it is a single domain name or multiple domain name

set fn=%~1
if [%fn:~0,2%] == [*.] set fn=_wildcard.%fn:~2%

Setting a file name for configuration and certificates. If the (first) domain name in the list is a wildcard domain, replace the asterisk character with "wildcard" word. Otherwise just take the domain name. So requesting a *.mydomain.local certificates will generate wildcard.mydomain.local files, while requesting web1.mydomain.local certificate will generate web1.mydomain.local files.

%~1 - removing surrounding quotes around first argument. E.g. if the first argument is "something with spaces", the %~1 will remove the quotes.
%fn:~0,2% - substring, first two characters of the fn variable
%fn:~2% - substring, everything after 2nd character

echo [req]>%fn%.conf
echo default_bits = 2048>>%fn%.conf
echo prompt = no>>%fn%.conf
echo default_md = sha256>>%fn%.conf
echo distinguished_name = req_distinguished_name>>%fn%.conf
if [%addsan%] == [1] echo x509_extensions = v3_req>>%fn%.conf
echo [req_distinguished_name]>>%fn%.conf
echo CN = %~1>>%fn%.conf

Making the openssl configuration, named %fn%.conf.

if not [%addsan%] == [1] goto :makecert

Skip additional configuration if there is only one domain

echo [v3_req]>>%fn%.conf
echo subjectAltName = @san>>%fn%.conf
echo [san]>>%fn%.conf
set /a sanid = 0

Additional configuration sections for multiple domain names.

set /a sanid+=1
echo DNS.%sanid% = %~1>>%fn%.conf
if [%~1]==[] goto :makecert
goto :sanloop

Looping through the arguments.
set /a sanid+=1 - increment counter so that each DNS entry has it's own number
shift - shift arguments so that %2 becomes %1, %3 becomes %2, etc
if [%~1]==[] goto :makecert - once there are no more arguments, break the loop

openssl req -new -x509 -nodes -days 3650 -sha256 -newkey rsa:4096 -keyout %fn%.key -out %fn%.crt -config %fn%.conf

openssl pkcs12 -export -out %fn%.pfx -inkey %fn%.key -in %fn%.crt -name %friendly% -passout pass:

Finally, the openssl call. Frist create a new self signed certificate which is valid for 10 years, and then export it to pkcs#12 pfx file with an empty password.

Make sure that openssl is somewhere in PATH.


Top comments (0)