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:
- mydomain.local.conf - configuration file for openssl
- mydomain.local.key - private key
- mydomain.local.crt - certificate
- mydomain.local.pfx - a pkcs#12 file with both certificate and private key
Content of the generated mydomain.local.conf
file:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = req_distinguished_name
x509_extensions = v3_req
[req_distinguished_name]
CN = mydomain.local
[v3_req]
subjectAltName = @san
[san]
DNS.1 = mydomain.local
DNS.2 = *.mydomain.local
And the generated certificate looks like this:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
fc:55:a1:88:a5:68:67:0c
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = mydomain.local
Validity
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)
Modulus:
00:cb:d9:5c:bb:df:23:1e:69:5d:b2:45:06:d8:1f:
d9:d1:4a:37:07:ab:c7:86:77:e0:2f:88:36:dc:f4:
<...>
7d:70:b6:23:aa:9a:bc:57:83:c9:f8:13:3f:9f:b4:
01:54:71
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:mydomain.local, DNS:*.mydomain.local
Signature Algorithm: sha256WithRSAEncryption
b0:7b:4c:2c:f6:5e:40:2b:9d:9d:71:b1:d3:f8:0b:44:84:50:
d1:ea:b0:91:fb:61:7d:d8:f8:d9:ca:5d:c8:b2:bf:d4:5d:75:
<...>
5c:73:66:d1:52:10:11:2b:68:85:da:8a:16:3d:82:4f:0c:c5:
50:a5:85:81:4f:06:27:33
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.>>%fn%.conf
echo [req_distinguished_name]>>%fn%.conf
echo CN = %~1>>%fn%.conf
echo.>>%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.>>%fn%.conf
echo [san]>>%fn%.conf
set /a sanid = 0
Additional configuration sections for multiple domain names.
:sanloop
set /a sanid+=1
echo DNS.%sanid% = %~1>>%fn%.conf
shift
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
:makecert
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)