Created
January 5, 2022 13:05
-
-
Save evandrocoan/14531fa0d795fc8ed89b877eeec51665 to your computer and use it in GitHub Desktop.
Generated an ssl private/public SSL certificate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -x | |
set -eu -o pipefail | |
function printerror | |
{ | |
set +x | |
printf '\n' | |
printf 'Usage\n' | |
printf ' %s "key name" "key password" "servidor ip" "server name (i.e., $HOSTNAME)"\n' "$0" | |
printf '\n' | |
exit 0 | |
} | |
# Parameters | |
# $1 = certificate name | |
# $2 = certificate name CA | |
# $3 = password | |
if [[ -z "${1+x}" ]]; | |
then | |
printerror; | |
fi | |
certnamefile="${1}" | |
certnamecafile="${certnamefile}" | |
if [[ -z "${2+x}" ]]; | |
then | |
printerror; | |
fi | |
password="${2}" | |
if [[ -z "${3+x}" ]]; | |
then | |
printerror; | |
fi | |
serverip="${3}" | |
if [[ -z "${4+x}" ]]; | |
then | |
printerror; | |
fi | |
servername="${4}" | |
# Generate a new key | |
openssl genrsa -out "$certnamefile".key -aes128 -passout pass:"$password" 2048 | |
# Generate a certificate requisition | |
openssl req -new -key "$certnamefile".key -out "$certnamefile".csr -config <(printf '[ req ] | |
default_bits = 2048 | |
distinguished_name = req_distinguished_name | |
prompt = no | |
[req_distinguished_name] | |
C = BR | |
ST = Some State | |
L = SomeCity | |
O = CityOrg | |
OU = CityState | |
CN = localname | |
emailAddress = [email protected]') | |
# Generate a signed certificate through the certificate requisition | |
openssl x509 -req -days 99999 -in "$certnamefile".csr -signkey "$certnamecafile".key -out "$certnamefile".crt \ | |
-extfile <(printf "basicConstraints = CA:TRUE | |
subjectAltName = @alt_names | |
[alt_names] | |
IP.1 = 127.0.0.1 | |
IP.2 = 127.0.0.2 | |
IP.3 = 127.0.0.3 | |
IP.4 = 192.168.0.1 | |
IP.5 = 192.168.0.2 | |
IP.6 = 192.168.0.3 | |
IP.7 = ${serverip} | |
IP.8 = 192.168.0.9 | |
IP.9 = 169.254.217.244 | |
DNS.1 = ${serverip} | |
DNS.2 = 10.254.254.240 | |
DNS.3 = $servername | |
DNS.4 = localhost | |
DNS.5 = hostname | |
DNS.6 = localhost.localdomain | |
DNS.7 = dev.local | |
DNS.8 = 192.168.0.9 | |
DNS.9 = 169.254.217.244 | |
") | |
# See the generated certificate | |
openssl x509 -text -noout -in $certnamefile.crt | |
# Check is signature | |
openssl verify -CAfile $certnamecafile.crt $certnamefile.crt | |
# Creates a certifying unit | |
cat $certnamefile.crt $certnamefile.key > $certnamefile.pem | |
exit 0 | |
# https://stackoverflow.com/questions/50788043/how-to-trust-self-signed-localhost-certificates-on-linux-chrome-and-firefox | |
' | |
# TLDR | |
1. Create the file `generate.sh` | |
#!/usr/bin/env bash | |
find . \( -name "$1.*" -o -name "*.srl" \) -type f -delete | |
cp /usr/lib/ssl/openssl.cnf $1.cnf | |
python <( | |
cat << "END" | |
import sys | |
from ConfigParser import ConfigParser | |
from StringIO import StringIO | |
domain = sys.argv[1] | |
config = ConfigParser() | |
config.optionxform = lambda option: option | |
name = "{}.cnf".format(domain) | |
with open(name, "rb") as stream: | |
config.readfp(StringIO("[top]\n" + stream.read())) | |
config.set(" v3_ca ", "subjectKeyIdentifier", "hash") | |
config.set(" v3_ca ", "authorityKeyIdentifier", "keyid:always,issuer") | |
config.set(" v3_ca ", "basicConstraints", "critical, CA:TRUE, pathlen:3") | |
config.set(" v3_ca ", "keyUsage", "critical, cRLSign, keyCertSign") | |
config.set(" v3_ca ", "nsCertType", "sslCA, emailCA") | |
config.set(" v3_req ", "basicConstraints", "CA:FALSE") | |
config.set(" v3_req ", "keyUsage", "nonRepudiation, digitalSignature, keyEncipherment") | |
config.set(" v3_req ", "subjectAltName", "@alt_names") | |
config.remove_option(" v3_req ", "extendedKeyUsage") | |
config.add_section(" alt_names ") | |
config.set(" alt_names ", "DNS.1", domain) | |
config.set(" alt_names ", "DNS.2", "*.{}".format(domain)) | |
config.set(" req ", "req_extensions", "v3_req") | |
with open(name, "wb") as stream: | |
config.write(stream) | |
END | |
) $1 | |
tail -n +2 $1.cnf > $1.cnf.tmp && mv $1.cnf.tmp $1.cnf | |
echo "$1\n" | openssl genrsa -aes256 -out $1.ca.key 2048 | |
chmod 400 $1.ca.key | |
openssl req -new -x509 -subj "/CN=$1" -extensions v3_ca -days 3650 -key $1.ca.key -sha256 -out $1.ca.crt -config $1.cnf | |
openssl genrsa -out $1.key 2048 | |
openssl req -subj "/CN=$1" -extensions v3_req -sha256 -new -key $1.key -out $1.csr | |
openssl x509 -req -extensions v3_req -days 3650 -sha256 -in $1.csr -CA $1.ca.crt -CAkey $1.ca.key -CAcreateserial -out $1.crt -extfile $1.cnf | |
openssl x509 -in $1.crt -text -noout | |
2. Call `./generate.sh example.com` | |
> Requires Python 2 | |
---------- | |
> All credits go to [this excellent article][3] by Fabian Lee. | |
# Create a trusted CA and SAN certificate using OpenSSL | |
1. Customize openssl.cnf | |
2. Create CA certificate | |
3. Create Server certificate with SAN signed by CA | |
## Prerequisite | |
As a prerequisite, ensure the SSL packages are installed: | |
$ sudo apt install libssl1.0.0 -y | |
## Customized openssl.cnf | |
The first step is to grab the `openssl.cnf` template available on your system. On Ubuntu this can be found at `/usr/lib/ssl/openssl.cnf`. You may find this in `/System/Library/OpenSSL/` on MacOS, and `/etc/pki/tls` on Redhat variants. | |
export prefix="mydomain" | |
cp /usr/lib/ssl/openssl.cnf $prefix.cnf | |
`$prefix.cnf` needs be modified with the specific information about the cert we are going to generate. | |
Under the `[ v3_ca ]` section, add the following values. For the CA, this signifies we are creating a CA that will be used for key signing. | |
[ v3_ca ] | |
subjectKeyIdentifier=hash | |
authorityKeyIdentifier=keyid:always,issuer | |
basicConstraints = critical, CA:TRUE, pathlen:3 | |
keyUsage = critical, cRLSign, keyCertSign | |
nsCertType = sslCA, emailCA | |
Then under the `[ v3_req ]` section, set the following along with all the valid alternative names for this certificate. | |
[ v3_req ] | |
basicConstraints = CA:FALSE | |
keyUsage = nonRepudiation, digitalSignature, keyEncipherment | |
#extendedKeyUsage=serverAuth | |
subjectAltName = @alt_names | |
[ alt_names ] | |
DNS.1 = mydomain.com | |
DNS.2 = *.dydomain.com | |
Also uncomment the following line under the `[ req ]` section so that certificate requests are created with v3 extensions. | |
req_extensions = v3_req | |
When we generate each type of key, we specify which extension section we want to use, which is why we can share `$prefix.cnf` for creating both the CA as well as the SAN certificate. | |
## Create CA Certificate | |
Now we will start using OpenSSL to create the necessary keys and certificates. First generate the private/public RSA key pair: | |
openssl genrsa -aes256 -out ca.key.pem 2048 | |
chmod 400 ca.key.pem | |
This encodes the key file using an passphrase based on AES256. | |
Then we need to create the self-signed root CA certificate. | |
openssl req -new -x509 -subj "/CN=myca" -extensions v3_ca -days 3650 -key ca.key.pem -sha256 -out ca.pem -config $prefix.cnf | |
You can verify this root CA certificate using: | |
openssl x509 -in ca.pem -text -noout | |
This will show the root CA certificate, and the `Issuer` and `Subject` will be the same since this is self-signed. This is flagged as `CA:TRUE` meaning it will be recognized as a root CA certificate; meaning browsers and OS will allow it to be imported into their trusted root certificate store. | |
Issuer: CN=myca | |
... | |
Subject: CN=myca | |
... | |
X509v3 Basic Constraints: | |
critical CA:TRUE, pathlen:3 | |
X509v3 Key Usage: | |
critical Certificate Sign, CRL Sign | |
Netscape Cert Type: | |
SSL CA, S/MIME CA | |
## Create Server certificate signed by CA | |
With the root CA now created, we switch over to the server certificate. First generate the private/public RSA key pair: | |
openssl genrsa -out $prefix.key.pem 2048 | |
We didn’t put a passphrase on this key simply because the CA is more valuable target and we can always regenerate the server cert, but feel free to take this extra precaution. | |
Then create the server cert signing request: | |
openssl req -subj "/CN=$prefix" -extensions v3_req -sha256 -new -key $prefix.key.pem -out $prefix.csr | |
Then generate the server certificate using the: server signing request, the CA signing key, and CA cert. | |
openssl x509 -req -extensions v3_req -days 3650 -sha256 -in $prefix.csr -CA ca.pem -CAkey ca.key.pem -CAcreateserial -out $prefix.crt -extfile $prefix.cnf | |
The `$prefix.key.pem` is the server private key and `$prefix.crt` is the server certificate. Verify the certificate: | |
openssl x509 -in $prefix.crt -text -noout | |
This will show the certificate, and the `Issuer` will be the CA name, while the Subject is the prefix. This is not set to be a CA, and the `Subject Alternative Name` field contains the URLs that will be considered valid by browsers. | |
Issuer: | |
CN=myca | |
... | |
Subject: | |
CN=mydomain | |
... | |
X509v3 Basic Constraints: | |
CA:FALSE | |
X509v3 Key Usage: | |
Digital Signature, Non Repudiation, Key Encipherment | |
X509v3 Subject Alternative Name: | |
DNS:mydomain.com, DNS:*.mydomain.com | |
## Browser Evaluation | |
When you first point Chrome or Firefox at the site with your SAN cert with CA signing, it will throw the same type of exceptions as a self-signed SAN cert. This is because the root CA cert is not known as a trusted source for signed certificates. | |
### Chrome | |
#### **Linux** | |
On Linux, Chrome manages its own certificate store and again you should import `ca.pem` into the `Authorities`. This should now make the security icon turn green. | |
[![enter image description here][1]][1] | |
#### **Windows** | |
In Chrome settings (`chrome://settings`), search for `certificates` and click on `Manage Certificates`. On Windows this will open the Windows certificate manager and you should import the `ca.pem` file at the `Trusted Root Certification Authorities` tab. This is equivalent to adding it through `mmc.exe`, in the `local user` trusted root store (not the computer level). | |
#### **Firefox** | |
In Firefox Options `about:preferences`, search for `certificates` and click `View Certificates`. Go to the `Authorities` tab and import `ca.pem`. Check the box to have it trust websites, and now the lock icon should turn green when you visit the page. | |
[![enter image description here][2]][2] | |
[1]: https://i.stack.imgur.com/geaeq.png | |
[2]: https://i.stack.imgur.com/JtaTa.png | |
[3]: https://fabianlee.org/2018/02/17/ubuntu-creating-a-trusted-ca-and-san-certificate-using-openssl-on-ubuntu/ | |
' | |
# https://stackoverflow.com/questions/52373778/neterr-cert-common-name-invalid-using-nettys-websocket | |
' | |
ERR_CERT_COMMON_NAME_INVALID, this happens when the domain name inside the certificate file is differend from the domain name the client is trying to connect to, can you post both domain names? | |
' | |
# https://serverfault.com/questions/880804/can-not-get-rid-of-neterr-cert-common-name-invalid-error-in-chrome-with-self | |
' | |
[Chrome 58+ no longer matches the Common Name (`CN`) in certs.](https://groups.google.com/a/chromium.org/forum/#!topic/security-dev/IGT2fLJrAeo) | |
Now it uses Subject Alternative Names (`SAN`) instead. | |
`SAN` must contain proper `DNS` or `IP` entry. | |
- When DNS is used, it should be a resolvable FQDN name. | |
- When an IP address is used, it should be explicitely specified as | |
such within the `SAN` chain. | |
That said, this should work : | |
openssl req \ | |
-newkey rsa:2048 \ | |
-x509 \ | |
-nodes \ | |
-keyout file.key \ | |
-new \ | |
-out file.crt \ | |
-subj /CN=Hostname \ | |
-reqexts SAN \ | |
-extensions SAN \ | |
-config <(cat /etc/ssl/openssl.cnf \ | |
<(printf "[SAN]\nsubjectAltName=DNS:hostname,IP:192.168.0.1")) \ | |
-sha256 \ | |
-days 3650 | |
Specifically, this is due to tools.ietf.org/html/rfc6125#section-5.7.3.1 which states "For TLS authentication with X.509 certificates, an identity from the DNS namespace MUST be checked against each subjectAltName extension of type dNSName present in the certificate. If no such extension is present, then the identity MUST be compared to the (most specific) Common Name in the Subject field of the certificate." So, if any SAN exists then the CN is not checked. | |
Life saver. For anyone trying this out on Windows, Cygwin comes with a copy of openssl.cnf here: .\cygwin\etc\defaults\etc\pki\tls\ Also, I had to change my CN=hostname and DNS:hostname lines to be localhost instead of hostname | |
' | |
# https://stackoverflow.com/questions/66558788/how-to-create-a-self-signed-ssl-certificate-for-ip-address-that-pass-chrome-requ | |
' | |
1. Prepare config files for creating certificates non-interactivelly (without prompts) | |
`CA.cnf` → | |
``` | |
[ req ] | |
prompt = no | |
distinguished_name = req_distinguished_name | |
[ req_distinguished_name ] | |
C = US | |
ST = Localzone | |
L = localhost | |
O = Certificate Authority Local Center | |
OU = Develop | |
CN = develop.localhost.localdomain | |
emailAddress = [email protected] | |
``` | |
`localhost.cnf` → | |
``` | |
[req] | |
default_bits = 2048 | |
distinguished_name = req_distinguished_name | |
req_extensions = req_ext | |
x509_extensions = v3_req | |
prompt = no | |
[req_distinguished_name] | |
countryName = US | |
stateOrProvinceName = Localzone | |
localityName = Localhost | |
organizationName = Self-signed certificate | |
commonName = localhost.localdomain | |
[req_ext] | |
subjectAltName = @alt_names | |
[v3_req] | |
subjectAltName = @alt_names | |
[alt_names] | |
IP.1 = 127.0.0.1 | |
IP.2 = 127.0.0.2 | |
IP.3 = 127.0.0.3 | |
IP.4 = 192.168.0.1 | |
IP.5 = 192.168.0.2 | |
IP.6 = 192.168.0.3 | |
DNS.1 = localhost | |
DNS.2 = localhost.localdomain | |
DNS.3 = dev.local | |
``` | |
2. Generate a CA private key and Certificate (valid for 5 years) | |
``` | |
openssl req -nodes -new -x509 -keyout CA_key.pem -out CA_cert.pem -days 1825 -config CA.cnf | |
``` | |
3. Generate web server secret key and CSR | |
``` | |
openssl req -sha256 -nodes -newkey rsa:2048 -keyout localhost_key.pem -out localhost.csr -config localhost.cnf | |
``` | |
4. Create self-signed certificate ([valid 1 year][1]) | |
``` | |
openssl x509 -req -days 398 -in localhost.csr -CA CA_cert.pem -CAkey CA_key.pem -CAcreateserial -out localhost_cert.pem -extensions req_ext -extfile localhost.cnf | |
``` | |
5. Profit | |
Output files will be: | |
- `CA.cnf` → OpenSSL CA config file. May be deleted after certificate creation process. | |
- `CA_cert.pem` → [Certificate Authority] certificate. This certificate must be added to the browser local authority storage to make trust all certificates that created with using this CA. | |
- `CA_cert.srl` → Random serial number. May be deleted after certificate creation process. | |
- `CA_key.pem` → Must be used when creating new [localhost] certificate. May be deleted after certificate creation process (if you do not plan reuse it and CA_cert.pem). | |
- `localhost.cnf` → OpenSSL SSL certificate config file. May be deleted after certificate creation process. | |
- `localhost.csr` → Certificate Signing Request. May be deleted after certificate creation process. | |
- `localhost_cert.pem` → SSL certificate. Must be installed at WEB server. | |
- `localhost_key.pem` → Secret key. Must be installed at WEB server. | |
SSL Certificate alternative names can be checked by | |
``` | |
openssl x509 -noout -text -in localhost_cert.pem | grep "X509v3 Subject Alternative Name" -A 1 | |
``` | |
[1]: https://www.certisur.com/en/google-chrome-limits-the-validity-of-ssl-certificates-to-one-year/ | |
' | |
# https://www.ibm.com/docs/en/ztpf/1.1.0.15?topic=gssccr-configuration-file-generating-self-signed-certificates-certificate-requests | |
' | |
[req] | |
days = daystocertify | |
serial = serialnumber | |
#The following three values can be anything; they just need to | |
#match a section name in the file. | |
distinguished_name = req_distinguished_name | |
req_extensions = v3_req | |
x509_extensions = v3_ca | |
[req_distinguished_name] | |
countryName = country | |
stateOrProvinceName = stateorprov | |
localityName = locality | |
organizationName = organization | |
organizationalUnitName = organizationalunit | |
commonName = commonname | |
emailAddress = emailaddress | |
[v3_req] | |
basicConstraints = CA:trueorfalse | |
keyUsage = keyusage | |
[v3_ca] | |
subjectKeyIdentifier = subjectkeyidentifier | |
authorityKeyIdentifier = authoritykeyidentifier | |
basicConstraints = basicconstraints | |
keyUsage = keyusage | |
subjectAltName = subjectaltname | |
issuerAltName = issueraltname | |
[req] | |
defines the sections in the certificate, along with the days and serial fields. This field is required, and must be exactly [req]. You can specify the following fields in this section: | |
days=daystocertify | |
specifies the number of days to certify a self-signed certificate, where daystocertify is an integer from 1–36500. If alphanumeric characters are specified, the number up to the first non-digit is accepted. (For example, 22FE is accepted as 22.) This field is required for both self-signed certificates and certificate requests, but has significance only for self-signed certificates. | |
serial=serialnumber | |
specifies the serial number to use when creating a self-signed certificate, where serialnumber is an integer value from 0–9999 or hexadecimal value from 0x0–0x270F. If alphanumeric characters are specified for the integer value, the number up to the first non-digit is accepted. (For example, 22FE is accepted as 22.) This field is optional. The default value is 0. | |
distinguished_name=req_distinguished_name | |
specifies the section that defines the information needed to generate a self-signed certificate or certificate request, where req_distinguished_name is the name of the section. At least one field must be specified in this section. See the following [req_distinguished_name] description for information about the fields that it can contain. This field is required for both self-signed certificates and certificate requests. | |
req_extensions=v3_req | |
specifies the section that defines extensions to add to a certificate request, where v3_req is the name of the section. See the following [v3_req] description for information about the fields that the section can contain. This field is optional. | |
x509_extensions=v3_ca | |
specifies the section that defines extensions to add to a self-signed certificate, where v3_ca is the name of the section. See the following [v3_ca] description for information about the fields that the section can contain. This field is optional. | |
[req_distinguished_name] | |
This is the value you specified on distinguished_name. You can specify more than one value for a field using the following syntax: | |
0.emailAddress=moe@curlyshouse | |
1.emailAddress=moe@larryshouse | |
2.emailAddress=moe@moeshouse | |
You can specify the following fields in this section: | |
countryName=country | |
specifies the two-character country name in ISO 3166 format. | |
stateOrProvinceName=stateorprov | |
specifies the state or province name, where stateorprov is 1–128 characters. | |
localityName=locality | |
specifies the locality name, where locality is 1–128 characters. | |
organizationName=organization | |
specifies the organization name, where organization is 1–64 characters. | |
organizationalUnitName=organizationalunit | |
specifies the organizational unit name, where organizationalunit is 1–64 characters. | |
commonName=commonname | |
specifies the common name, where commonname is 1–64 characters. | |
emailAddress=emailaddress | |
specifies the email address, where emailaddress is 1–64 characters. | |
[v3_req] | |
This is the value you specified on req_extensions. This section is optional. You can specify the following fields in this section: | |
basicConstraints=CA:trueorfalse | |
indicates whether a certificate is a certificate authority (CA), where trueorfalse is either TRUE or FALSE. | |
keyUsage=keyusage | |
specifies permitted key usages, where keyusage is a comma-separated list of any of the following: | |
digitalSignature | |
nonRepudiation | |
keyEncipherment | |
dataEncipherment | |
keyAgreement | |
keyCertSign | |
cRLSign | |
encipherOnly | |
decipherOnly. | |
[v3_ca] | |
This is the value you specified on x509_extensions. This section is optional. You can specify the following fields in this section: | |
subjectKeyIdentifier=subjectkeyidentifier | |
specifies how to identify the public key being certified. The only value supported for subjectkeyidentifier is hash. This field is required if x509_extensions is specified. | |
authorityKeyIdentifier=authoritykeyidentifier | |
specifies how to identify the public key being used to verify the signature on this certificate, and enables keys used by the same CA to be distinguished, where authoritykeyidentifier is one of the following: | |
keyid | |
indicates that the subject key identifier is copied from the parent certificate. | |
keyid:always | |
indicates that the subject key identifier is copied from the parent certificate and an error is returned if the copy fails. | |
issuer | |
indicates that the issuer and serial number is copied from the issuer certificate if the keyid option fails or is not specified. | |
issuer:always | |
indicates that the issuer and serial number is always copied from the issuer certificate. | |
basicConstraints=CA:trueorfalse | |
see basicConstraints description in the [v3_req] section. | |
keyUsage=keyusage | |
see keyUsage description in the [v3_req] section. | |
subjectAltName=subjectaltname | |
allows you to specify the following literal values in the configuration file: | |
email:email | |
specifies an email address. If copy is specified, all email addresses contained in the certificate are included. | |
URI:uri | |
specifies a uniform resource indicator. | |
DNS:dns | |
specifies a Domain Name System (DNS). | |
RID:rid | |
specifies a registered ID. | |
IP:IP | |
specifies an IP address in Internet Protocol version 4 (IPv4) format. | |
@dirname | |
specifies a section that contains a list of fields, where dirname is the section name and must be defined later in the configuration file (by placing it between square brackets). | |
issuerAltName=issueraltname | |
allows you to specify all literal values from subjectAltName except email:copy, including the following: | |
issuer:copy | |
all subject alternative name values from the issuer certificate are included. | |
# | |
#Creating a self-signed certificate | |
# | |
#################################################################### | |
[req] | |
days = 180 | |
serial = 1 | |
distinguished_name = req_distinguished_name | |
x509_extensions = v3_ca | |
[req_distinguished_name] | |
countryName = US | |
stateOrProvinceName = NY | |
localityName = POK | |
organizationName = IBM | |
organizationalUnitName = TPF | |
commonName = SSL_SERVER | |
0.emailAddress = [email protected] | |
1.emailAddress = [email protected] | |
2.emailAddress = [email protected] | |
[ v3_ca ] | |
# The extentions to add to a self-signed cert | |
subjectKeyIdentifier = hash | |
authorityKeyIdentifier = keyid:always,issuer:always | |
basicConstraints = CA:TRUE | |
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign | |
subjectAltName = DNS:moe.ibm.com, DNS:larry.ibm.com, email:[email protected] | |
issuerAltName = issuer:copy | |
# | |
#Creating a certificate request | |
# | |
#################################################################### | |
[req] | |
days = 180 | |
distinguished_name = req_distinguished_name | |
req_extensions = v3_req | |
[req_distinguished_name] | |
countryName = US | |
stateOrProvinceName = NY | |
localityName = POK | |
organizationName = IBM | |
organizationalUnitName = TPF | |
commonName = SSL_SERVER | |
0.emailAddress = [email protected] | |
1.emailAddress = [email protected] | |
2.emailAddress = [email protected] | |
[ v3_req ] | |
# Extensions to add to a certificate request | |
basicConstraints = CA:FALSE | |
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign | |
' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment