教程:使用 OpenSSL 创建测试证书
对于生产环境,建议从公共根证书颁发机构 (CA) 购买 X.509 CA 证书。 但是,自行创建测试证书层次结构足以测试 IoT 中心设备身份验证。 有关如何从公共根 CA 获取 X.509 CA 证书的详细信息,请参阅使用 X.509 CA 证书验证设备身份的获取 X.509 CA 证书部分。
以下示例使用 OpenSSL 和 OpenSSL 指南创建证书颁发机构 (CA)、从属 CA 和设备证书。 然后,该示例将从属 CA 和设备证书签名到证书层次结构中。 此示例仅用于演示目的。
注意
Microsoft 提供了 PowerShell 和 Bash 脚本来帮助你了解如何创建你自己的 x.509 证书,并将在 IoT 中心进行身份验证。 这些脚本包含在适用于 C 的 Azure IoT 中心设备 SDK 中。这些脚本仅用于演示目的。 所创建的证书不得用于生产。 证书包含硬编码密码(“1234”)并在 30 天后过期。 必须使用自己的最佳做法在生产环境中创建证书并管理生存期。 有关详细信息,请参阅适用于 C 的 Azure IoT 中心设备 SDK 的 GitHub 存储库中的管理测试 CA 证书示例和教程。
步骤 1 - 创建根 CA 目录结构
为证书颁发机构创建目录结构。
- certs 目录用于存储新证书。
- db 目录存储证书数据库。
- 专用目录用于存储 CA 私钥。
mkdir rootca
cd rootca
mkdir certs db private
touch db/index
openssl rand -hex 16 > db/serial
echo 1001 > db/crlnumber
步骤 2 - 创建根 CA 配置文件
创建 CA 之前,请先创建一个配置文件,并在 rootca 目录中将其另存为 rootca.conf。
[default]
name = rootca
domain_suffix = example.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align
[ca_dn]
commonName = "Test Root CA"
[ca_default]
home = ../rootca
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = none
default_days = 3650
default_crl_days = 365
default_md = sha256
policy = policy_c_o_match
[policy_c_o_match]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 2048
encrypt_key = yes
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dn
req_extensions = ca_ext
[ca_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
[sub_ca_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true,pathlen:0
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
[client_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = clientAuth
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
步骤 3 - 创建根 CA
首先,在 rootca 目录中生成私钥和证书签名请求 (CSR)。
openssl req -new -config rootca.conf -out rootca.csr -keyout private/rootca.key
接下来,创建自签名 CA 证书。 自签名适用于测试目的。 在命令行上指定 ca_ext
配置文件扩展名。 这些扩展名表示证书适用于根 CA,可用于签署证书和证书吊销列表 (CRL)。 签署证书,并将其提交至数据库。
openssl ca -selfsign -config rootca.conf -in rootca.csr -out rootca.crt -extensions ca_ext
步骤 4 - 创建从属 CA 目录结构
为从属 CA 创建一个与 rootca 目录同级的目录结构。
mkdir subca
cd subca
mkdir certs db private
touch db/index
openssl rand -hex 16 > db/serial
echo 1001 > db/crlnumber
步骤 5 - 创建从属 CA 配置文件
创建配置文件并在 subca 目录中将其另存为 subca.conf。
[default]
name = subca
domain_suffix = example.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align
[ca_dn]
commonName = "Test Subordinate CA"
[ca_default]
home = .
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = copy
default_days = 365
default_crl_days = 90
default_md = sha256
policy = policy_c_o_match
[policy_c_o_match]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 2048
encrypt_key = yes
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dn
req_extensions = ca_ext
[ca_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
[sub_ca_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true,pathlen:0
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
[client_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = clientAuth
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
步骤 6 - 创建从属 CA
此示例演示如何创建从属 CA 或注册 CA。 由于可以使用根 CA 签署证书,因此不一定要创建从属 CA。 但是,拥有从属 CA 确实可以模拟真实的证书层次结构,在该层次结构中,根 CA 处于脱机状态,从属 CA 为客户端颁发证书。
在 subca 目录中,使用配置文件生成私钥和证书签名请求 (CSR)。
openssl req -new -config subca.conf -out subca.csr -keyout private/subca.key
将 CSR 提交到根 CA,使用根 CA 颁发并签署从属 CA 证书。 在命令行上为扩展开关指定 sub_ca_ext
。 这些扩展表明,此证书适用于可签署证书和证书吊销列表 (CRL) 的 CA。 出现提示时,请签署证书,并将其提交到数据库。
openssl ca -config ../rootca/rootca.conf -in subca.csr -out subca.crt -extensions sub_ca_ext
步骤 7 - 展示所有权证明
现在,你同时拥有根 CA 证书和从属 CA 证书。 你可以使用其中任何一个来签署设备证书。 必须将你选择的证书上传到 IoT 中心。 以下步骤假定你使用的是从属 CA 证书。 若要将从属 CA 证书上传至 IoT 中心并进行注册,请执行以下操作:
在 Azure 门户中,导航到 IoT 中心,选择“设置”>“证书”。
选择“添加”,以添加新的从属 CA 证书。
在“证书名称”字段中输入显示名称,并选择之前创建的 PEM 证书文件。
注意
上面创建的 .crt 证书与 .pem 证书相同。 只需在为证明所有权而上传证书时更改扩展,或使用以下 OpenSSL 命令:
openssl x509 -in mycert.crt -out mycert.pem -outform PEM
选择“保存”。 此时证书显示在证书列表中,状态为“未验证”。 此验证过程将证明你已拥有证书。
选择证书以查看“证书详细信息”对话框。
选择“生成验证码”。 有关详细信息,请参阅证明对 CA 证书的所有权。
将验证码复制到剪贴板。 必须将验证码设置为证书使用者。 例如,如果验证码为 BB0C656E69AF75E3FB3C8D922C1760C58C1DA5B05AAA9D0A,请将其添加为证书使用者,如步骤 9 所示。
生成私钥。
openssl genpkey -out pop.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048
从私钥中生成证书签名请求 (CSR)。 添加验证码作为证书使用者。
openssl req -new -key pop.key -out pop.csr ----- Country Name (2 letter code) [XX]:. State or Province Name (full name) []:. Locality Name (eg, city) [Default City]:. Organization Name (eg, company) [Default Company Ltd]:. Organizational Unit Name (eg, section) []:. Common Name (eg, your name or your server hostname) []:BB0C656E69AF75E3FB3C8D922C1760C58C1DA5B05AAA9D0A Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
使用从属 CA 配置文件和所有权证明证书的 CSR 创建证书。
openssl ca -config subca.conf -in pop.csr -out pop.crt -extensions client_ext
在“证书详细信息”视图中选择新证书。 若要查找 PEM 文件,请导航到“certs”文件夹。
上传证书后,选择“验证”。 CA 证书状态应更改为“已验证”。
步骤 8 - 在 IoT 中心创建设备
在 Azure 门户中,导航到 IoT 中心,并使用以下值创建新 IoT 设备标识:
提供与设备证书的使用者名称匹配的设备 ID。
选择“X.509 CA 签名”身份验证类型。
选择“保存”。
步骤 9 - 创建客户端设备证书
若要生成客户端证书,必须首先生成私钥。 以下命令演示如何使用 OpenSSL 创建私钥。 在 subca 目录中创建密钥。
openssl genpkey -out device.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048
为密钥创建证书签名请求 (CSR)。 无需输入质询密码或可选公司名称。 但是,必须在“公用名”字段中输入设备 ID。 还可以为其他参数(例如“国家/地区名称”、“组织名称”等)输入自定义值。
openssl req -new -key device.key -out device.csr
-----
Country Name (2 letter code) [XX]:.
State or Province Name (full name) []:.
Locality Name (eg, city) [Default City]:.
Organization Name (eg, company) [Default Company Ltd]:.
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server hostname) []:`<your device ID>`
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
检查 CSR 是否符合预期。
openssl req -text -in device.csr -noout
将 CSR 发送到从属 CA,以登录到证书层次结构。 在 -extensions
开关中指定 client_ext
。 请注意,已颁发证书中的 Basic Constraints
表示此证书不适用于 CA。 若要签署多个证书,请确保在使用 openssl rand -hex 16 > db/serial
命令生成每个证书之前更新序列号。
openssl ca -config subca.conf -in device.csr -out device.crt -extensions client_ext
后续步骤
转到教程:测试证书身份验证,以确定证书是否可在 IoT 中心用于对设备进行身份验证。 该页上的代码要求使用 PFX 证书。 使用以下 OpenSSL 命令将设备 .crt 证书转换为 .pfx 格式。
openssl pkcs12 -export -in device.crt -inkey device.key -out device.pfx