2.3. Initialize EC Intermediate CA
该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/en/book/pki-tutorials/2.3.generate-ec-ca-intermediate/
This chapter describes how to generate an intermediate CA with EC key, using OpenSSL command-line tools.
Initialize Working Directory
Assuming the working directory of the EC CA is /data/ca/EC/R1
, let’s begin by executing the following script:
1export MY_CA_WORKDIR=/data/ca
2mkdir -p $MY_CA_WORKDIR
3MY_CA_ROOT_DIR=$MY_CA_WORKDIR/EC/Root
4MY_CA_ROOT_CERT_PATH=$MY_CA_ROOT_DIR/ca.pem
5MY_CA_L2_DIR=$MY_CA_WORKDIR/EC/E1
6
7mkdir -p $MY_CA_L2_DIR
8
9cd $MY_CA_L2_DIR
10MY_CA_RAND_FILE=$MY_CA_L2_DIR/.rand
11
12mkdir -p certs crl csr issued_certs private
13touch index.txt
14
15openssl rand -out $MY_CA_RAND_FILE 65535
16sha1sum $MY_CA_RAND_FILE | grep -Po '^\w+' > serial
17
18openssl rand -out $MY_CA_RAND_FILE 65535
19sha1sum $MY_CA_RAND_FILE | grep -Po '^\w+' > crlnumber
20
21openssl rand -out $MY_CA_RAND_FILE 1048576
Generate EC private key for the intermediate CA
1MY_CA_L2_KEY_PATH=$MY_CA_L2_DIR/key.pem
2
3openssl ecparam -rand $MY_CA_RAND_FILE -genkey -name secp384r1 -noout -out $MY_CA_L2_KEY_PATH
4openssl ec -aes-256-cfb -in $MY_CA_L2_KEY_PATH -out $MY_CA_L2_KEY_PATH
Generate Certificate Signing Request (CSR) File
Different from the root CA, the intermediate CA can not be self-signed, It must be signed by a root CA.
So, you need to sign a .csr.pem
file with the private key of the intermediate CA.
Let’s create a text file named ca.csr.cnf
as a draft for the certificate signing request (CSR), which describes the detailed information of the certificate to be applied for.
You can replace the content of
req_distinguished_name
section with your own information.
1MY_CA_L2_REQ_PATH=$MY_CA_L2_DIR/ca.csr.cnf
2
3cat > $MY_CA_L2_REQ_PATH << EOL
4[ req ]
5default_bits = 4096
6distinguished_name = req_distinguished_name
7string_mask = utf8only
8
9# SHA-1 is deprecated, so use SHA-2 instead.
10default_md = sha384
11prompt = no
12
13[ req_distinguished_name ]
14# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
15countryName = CN
160.organizationName = Demo ORG
17organizationalUnitName = www.demo.org
18commonName = Demo CA EC E1
19EOL
Now, create a certificate signing request (CSR) file ca.csr.pem
by signing the draft file with the private key of the intermediate CA.
1MY_CA_L2_CSR_PATH=$MY_CA_L2_DIR/ca.csr.pem
2
3openssl req \
4 -config $MY_CA_L2_REQ_PATH \
5 -new \
6 -key $MY_CA_L2_KEY_PATH \
7 -out $MY_CA_L2_CSR_PATH
You can check it out by the following command:
1openssl req \
2 -in $MY_CA_L2_CSR_PATH \
3 -noout \
4 -text
Sign Intermediate CA Certificate
Now, you can sign the intermediate CA certificate with the root CA certificate.
Here is how to sign an intermediate CA certificate:
The intermediate CA certificate is valid for 10 years from the current date.
1MY_CA_L2_CERT_PATH=$MY_CA_L2_DIR/ca.pem
2
3openssl ca \
4 -config $MY_CA_ROOT_DIR/ca.cnf \
5 -extensions v3_intermediate_ca \
6 -days 3650 \
7 -notext \
8 -md sha384 \
9 -batch \
10 -in $MY_CA_L2_CSR_PATH \
11 -out $MY_CA_L2_CERT_PATH
Let’s check the detailed information of the new issued certificate.
1openssl x509 -noout -text -in $MY_CA_L2_CERT_PATH
And you can verify the intermediate CA certificate with the root CA certificate.
1openssl verify -CAfile $MY_CA_ROOT_CERT_PATH $MY_CA_L2_CERT_PATH
Generate Certificate Chain File
The intermediate CA certificate can not be verified alone, you need to combine it with the root CA certificate, and turn them into a certificate chain file, like this:
1MY_CA_L2_CERT_CHAIN_PATH=$MY_CA_L2_DIR/ca.fullchain.pem
2
3cat > $MY_CA_L2_CERT_CHAIN_PATH << EOL
4$(cat $MY_CA_L2_CERT_PATH)
5
6$(cat $MY_CA_ROOT_CERT_PATH)
7EOL
Setup the Intermediate CA
Finally, configure the intermediate CA for issuing other certificates.
Still, you can modify the configuration file
ca.cnf
to meet your requirements. Especially, you can change theserver_cert
section andclient_cert
section to match your organization’s information.
1MY_CA_L2_CONF_PATH=$MY_CA_L2_DIR/ca.cnf
2
3cat > $MY_CA_L2_CONF_PATH << EOL
4[ ca ]
5# man ca
6default_ca = CA_default
7
8[ CA_default ]
9# Directory and file locations.
10dir = $MY_CA_L2_DIR
11certs = \$dir/certs
12crl_dir = \$dir/crl
13new_certs_dir = \$dir/issued_certs
14database = \$dir/index.txt
15serial = \$dir/serial
16RANDFILE = \$dir/.rand
17
18# The root key and root certificate.
19private_key = \$dir/key.pem
20certificate = \$dir/ca.pem
21
22# For certificate revocation lists.
23crlnumber = \$dir/crlnumber
24crl = \$dir/crl/intermediate.crl.pem
25crl_extensions = crl_ext
26default_crl_days = 30
27
28# SHA-1 is deprecated, so use SHA-2 instead.
29default_md = sha256
30
31name_opt = ca_default
32cert_opt = ca_default
33default_days = 375
34preserve = no
35policy = policy_loose
36copy_extensions = copy
37
38[ policy_loose ]
39# Allow the intermediate CA to sign a more diverse range of certificates.
40# See the POLICY FORMAT section of the ca man page.
41countryName = optional
42stateOrProvinceName = optional
43localityName = optional
44organizationName = optional
45organizationalUnitName = optional
46commonName = supplied
47emailAddress = optional
48
49[ client_cert ]
50# Extensions for client certificates (man x509v3_config).
51basicConstraints = CA:FALSE
52subjectKeyIdentifier = hash
53authorityKeyIdentifier = keyid:always,issuer:always
54keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
55extendedKeyUsage = clientAuth
56# authorityInfoAccess = caIssuers;URI:http://demo.org/ca.html
57# certificatePolicies = 2.23.140.1.2.1,@policy_issuer_info
58# authorityInfoAccess = OCSP;URI:http://ocsp.demo.org/
59
60[ server_cert ]
61# Extensions for server certificates (man x509v3_config).
62keyUsage = critical, digitalSignature, keyEncipherment
63extendedKeyUsage = serverAuth, clientAuth
64basicConstraints = CA:FALSE
65subjectKeyIdentifier = hash
66authorityKeyIdentifier = keyid:always,issuer:always
67# authorityInfoAccess = caIssuers;URI:http://demo.org/ca.html
68# certificatePolicies = 2.23.140.1.2.1,@policy_issuer_info
69# authorityInfoAccess = OCSP;URI:http://ocsp.demo.org/
70
71# [ policy_issuer_info ]
72# policyIdentifier = 1.3.6.1.4.1.44947.1.2.3.4.5.6.7.8
73# CPS.1 = "http://cps.demo.org/"
74# userNotice.1 = @policy_issuer_notice
75
76# [ policy_issuer_notice ]
77
78# explicitText="This is a demo certificate"
79# organization="Demo ORG"
80
81EOL
Well, remember to update the index.txt.attr
file to allow the CA to reissue certificates with the same commonName
.
1echo 'unique_subject = no' > $MY_CA_ROOT_DIR/index.txt.attr
Finally, an intermediate CA with RSA key is ready.