1.3. Initialize RSA Intermediate CA

该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/en/book/pki-tutorials/1.3.generate-rsa-ca-intermediate/

Overview

This chapter describes how to generate an intermediate CA with RSA key, using OpenSSL command-line tools.

Assuming the working directory of the RSA CA is /data/ca/RSA/R1, let’s begin by executing the following script:

 1export MY_CA_WORKDIR=/data/ca
 2
 3MY_CA_L2_DIR=$MY_CA_WORKDIR/RSA/R1
 4
 5mkdir -p $MY_CA_L2_DIR
 6
 7cd $MY_CA_L2_DIR
 8
 9mkdir -p certs crl csr issued_certs private
10touch index.txt
11
12MY_CA_RAND_FILE=$MY_CA_L2_DIR/.rand
13
14openssl rand -out $MY_CA_RAND_FILE 65535
15sha1sum $MY_CA_RAND_FILE | grep -Po '^\w+' > serial
16
17openssl rand -out $MY_CA_RAND_FILE 65535
18sha1sum $MY_CA_RAND_FILE | grep -Po '^\w+' > crlnumber
19
20openssl rand -out $MY_CA_RAND_FILE 1048576
bash
1MY_CA_L2_KEY_PATH=$MY_CA_L2_DIR/key.pem
2
3# A 3072-bit RSA private key for an intermediate CA should be secure enough
4openssl genrsa -rand $MY_CA_RAND_FILE -aes-256-cfb -out $MY_CA_L2_KEY_PATH 3072
bash

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 ]
 5distinguished_name  = req_distinguished_name
 6string_mask         = utf8only
 7
 8# SHA-1 is deprecated, so use SHA-2 instead.
 9default_md          = sha384
10prompt              = no
11
12[ req_distinguished_name ]
13# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
14countryName                     = US
150.organizationName              = Demo ORG
16organizationalUnitName          = www.demo.org
17commonName                      = Demo CA RSA R1
18EOL
bash

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
bash

You can check it out by the following command:

1openssl req \
2    -in $MY_CA_L2_CSR_PATH \
3    -noout \
4    -text
bash

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    -batch \
 9    -in $MY_CA_L2_CSR_PATH \
10    -out $MY_CA_L2_CERT_PATH
bash

Let’s check the detailed information of the new issued certificate.

1openssl x509 -noout -text -in $MY_CA_L2_CERT_PATH
bash

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
bash

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
bash

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 the server_cert section and client_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# OpenSSL intermediate CA configuration file.
 5# Copy to /root/ca/intermediate/openssl.cnf.
 6
 7[ ca ]
 8# man ca
 9default_ca = CA_default
10
11[ CA_default ]
12# Directory and file locations.
13dir               = $MY_CA_L2_DIR
14certs             = \$dir/certs
15crl_dir           = \$dir/crl
16new_certs_dir     = \$dir/issued_certs
17database          = \$dir/index.txt
18serial            = \$dir/serial
19RANDFILE          = \$dir/.rand
20
21# The root key and root certificate.
22private_key       = \$dir/key.pem
23certificate       = \$dir/ca.pem
24
25# For certificate revocation lists.
26crlnumber         = \$dir/crlnumber
27crl               = \$dir/crl/intermediate.crl.pem
28crl_extensions    = crl_ext
29default_crl_days  = 30
30
31# SHA-1 is deprecated, so use SHA-2 instead.
32default_md        = sha256
33
34name_opt          = ca_default
35cert_opt          = ca_default
36default_days      = 375
37preserve          = no
38policy            = policy_loose
39copy_extensions   = copy
40
41[ policy_loose ]
42# Allow the intermediate CA to sign a more diverse range of certificates.
43# See the POLICY FORMAT section of the ca man page.
44countryName             = optional
45stateOrProvinceName     = optional
46localityName            = optional
47organizationName        = optional
48organizationalUnitName  = optional
49commonName              = supplied
50emailAddress            = optional
51
52[ client_cert ]
53# Extensions for client certificates (man x509v3_config).
54basicConstraints = CA:FALSE
55subjectKeyIdentifier = hash
56authorityKeyIdentifier = keyid:always,issuer:always
57keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
58extendedKeyUsage = clientAuth
59# authorityInfoAccess = caIssuers;URI:http://demo.org/ca.html
60# certificatePolicies = 2.23.140.1.2.1,@policy_issuer_info
61# authorityInfoAccess = OCSP;URI:http://ocsp.demo.org/
62
63[ server_cert ]
64# Extensions for server certificates (man x509v3_config).
65keyUsage = critical, digitalSignature, keyEncipherment
66extendedKeyUsage = serverAuth, clientAuth
67basicConstraints = CA:FALSE
68subjectKeyIdentifier = hash
69authorityKeyIdentifier = keyid:always,issuer:always
70# authorityInfoAccess = caIssuers;URI:http://demo.org/ca.html
71# certificatePolicies = 2.23.140.1.2.1,@policy_issuer_info
72# authorityInfoAccess = OCSP;URI:http://ocsp.demo.org/
73
74# [ policy_issuer_info ]
75# policyIdentifier = 1.3.6.1.4.1.44947.1.2.3.4.5.6.7.8
76# CPS.1 = "http://cps.demo.org/"
77# userNotice.1 = @policy_issuer_notice
78
79# [ policy_issuer_notice ]
80
81# explicitText="This is a demo certificate"
82# organization="Demo ORG"
83
84EOL
bash

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
bash

Finally, an intermediate CA with RSA key is ready.

Translations: