Skip to content

Commit f643135

Browse files
committed
Draft, in progress
1 parent 6105570 commit f643135

File tree

1 file changed

+83
-52
lines changed

1 file changed

+83
-52
lines changed

articles/iot-hub/tutorial-x509-test-ca-certs.md

Lines changed: 83 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
title: Tutorial - Create a root CA and certificates for testing | Microsoft Docs
3-
description: Tutorial - Create a root certificate authority and use it to make and sign certificates that you can use for testing purposes with Azure IoT Hub
2+
title: Tutorial - Create and upload certificates for testing | Microsoft Docs
3+
description: Tutorial - Create a root certificate authority and use it to make and sign subordinate CA and client certificates that you can use for testing purposes with Azure IoT Hub
44
author: kgremban
55

66
ms.service: iot-hub
@@ -12,7 +12,19 @@ ms.custom: [mvc, 'Role: Cloud Development', 'Role: Data Analytics']
1212
#Customer intent: As a developer, I want to be able to use X.509 certificates to test my devices on an IoT hub.
1313
---
1414

15-
# Tutorial: Create a root CA and certificates for testing
15+
# Tutorial: Create and upload certificates for testing
16+
17+
For production environments, we recommend that you purchase an X.509 CA certificate from a commercial certificate authority (CA) and issue certificates within your organization from internal, self-managed subordinate CAs that are chained to the external root CA as part of a comprehensive public key infrastructure (PKI) strategy. For more information about getting an X.509 CA certificate from a commercial CA, see the [Get an X.509 CA certificate](iot-hub-x509ca-overview.md#get-an-x509-ca-certificate) section of [Authenticate devices using X.509 CA certificates](iot-hub-x509ca-overview.md).
18+
19+
However, creating your own self-managed, private CA that uses an internal root CA as the trust anchor is adequate for testing environments. Using a self-managed private CA with at least one subordinate CA chained to your internal root CA, and client certificates for your devices issued by your subordinate CA certificates, allows you to more closely simulate a recommended production environment.
20+
21+
>[!NOTE]
22+
>We do not recommend the use of a self-managed PKI or self-signed certificates for production environments.
23+
24+
The following tutorial uses [OpenSSL](https://www.openssl.org/) and the [OpenSSL Cookbook](https://www.feistyduck.com/library/openssl-cookbook/online/ch-openssl.html) to create a self-signed internal root certificate authority (CA) and a subordinate CA, then shows how to upload your internal subordinate CA certificate to your IoT hub for testing purposes. The example then signs the subordinate CA and the device certificate into a certificate hierarchy. This example is presented for demonstration purposes only.
25+
26+
>[!NOTE]
27+
>Microsoft provides PowerShell and Bash scripts to help you understand how to create your own X.509 certificates and authenticate them to an IoT hub. The scripts are included with the [Azure IoT Hub Device SDK for C](https://github.com/Azure/azure-iot-sdk-c). The scripts are provided for demonstration purposes only. Certificates created by them must not be used for production. The certificates contain hard-coded passwords (“1234”) and expire after 30 days. You must use your own best practices for certificate creation and lifetime management in a production environment. For more information, see [Managing test CA certificates for samples and tutorials](https://github.com/Azure/azure-iot-sdk-c/blob/main/tools/CACertificates/CACertificateOverview.md) in the GitHub repository for the [Azure IoT Hub Device SDK for C](https://github.com/Azure/azure-iot-sdk-c).
1628
1729
## Prerequisites
1830

@@ -36,11 +48,11 @@ Proc
3648
| --- | --- |
3749
| rootca | The root folder of the root CA. |
3850
| rootca/certs | The folder in which CA certificates for the root CA are created and stored. |
39-
| rootca/db | The folder in which the database for the root CA is stored. |
40-
| rootca/db/index | The index file for the root CA. The `touch` command creates a file without any content, for later use. |
41-
| rootca/db/serial | The serial number file for the root CA. The `openssl` command creates a 16-byte random number in hexadecimal format, then stores it in this file. |
42-
| rootca/db/crlnumber | A file used to store serial numbers for revoked CA certificates issued by the root CA. The `echo` command pipes a sample serial number, 1001, into the file. |
43-
| rootca/private | The folder in which private files for the root CA, including the private key, are stored. |
51+
| rootca/db | The folder in which the certificate database and support files for the root CA are stored. |
52+
| rootca/db/index | The certificate database for the root CA. The `touch` command creates a file without any content, for later use. The certificate database is a plain text file managed by OpenSSL that contains certificate information. For more information about the certificate database, see .|
53+
| rootca/db/serial | A file used to store the serial number of the next certificate to be created for the root CA. The `openssl` command creates a 16-byte random number in hexadecimal format, then stores it in this file to initialize the file for creating the root CA certificate. |
54+
| rootca/db/crlnumber | A file used to store serial numbers for revoked certificates issued by the root CA. The `echo` command pipes a sample serial number, 1001, into the file. |
55+
| rootca/private | The folder in which private files for the root CA, including the private key, are stored.<br/><br/>The files in this folder must be secured and protected. |
4456

4557
```bash
4658
mkdir rootca
@@ -51,24 +63,33 @@ Proc
5163
echo 1001 > db/crlnumber
5264
```
5365

54-
1. Create a text file named *rootca.conf* in the *rootca* folder created in the previous step, then copy and save the following OpenSSL configuration settings into that file. The file provides OpenSSL with the values needed to configure your test root CA. For this example, the file configures a root CA named *rootca* for the *example.com* domain, using the folders and files created in previous steps. The file also provides configuration settings for:
66+
1. Create a text file named *rootca.conf* in the *rootca* folder created in the previous step. Open that file in a text editor, and then copy and save the following OpenSSL configuration settings into that file, replacing the following placeholders with corresponding values.
67+
68+
| Placeholder | Description |
69+
| --- | --- |
70+
| {CA_Name} | The name of the root CA. For example, `rootca`.|
71+
| {Domain_Suffix} | The suffix of the domain name for the root CA. For example, `example.com`. |
72+
| {Common_Name} | The common name of the root CA. For example, `Test Root CA`. |
73+
74+
The file provides OpenSSL with the values needed to configure your test root CA. For this example, the file configures a root CA using the folders and files created in previous steps. The file also provides configuration settings for:
5575
- The CA policy used by the root CA for certificate Distinguished Name (DN) fields
5676
- Certificate requests created by the root CA
57-
- X.509 extensions applied to root CA certificates, intermediate CA certificates, and client certificates issued by the root CA
77+
- X.509 extensions applied to root CA certificates, subordinate CA certificates, and client certificates issued by the root CA
78+
The root CA certificate generated from this configuration file is valid for 3650 days,
5879

5980
For more information about the syntax of OpenSSL configuration files, see the [config](https://www.openssl.org/docs/manmaster/man5/config.html) master manual page in [OpenSSL documentation](https://www.openssl.org/docs/).
6081

6182
```xml
6283
[default]
63-
name = rootca
64-
domain_suffix = example.com
84+
name = {CA_Name}
85+
domain_suffix = {Domain_Suffix}
6586
aia_url = http://$name.$domain_suffix/$name.crt
6687
crl_url = http://$name.$domain_suffix/$name.crl
6788
default_ca = ca_default
6889
name_opt = utf8,esc_ctrl,multiline,lname,align
6990
7091
[ca_dn]
71-
commonName = "Test Root CA"
92+
commonName = "{Common_Name}"
7293
7394
[ca_default]
7495
home = ../rootca
@@ -121,11 +142,13 @@ Proc
121142
basicConstraints = critical,CA:false
122143
extendedKeyUsage = clientAuth
123144
keyUsage = critical,digitalSignature
124-
subjectKeyIdentifier = hash
125-
145+
subjectKeyIdentifier = hash
126146
```
127147

128-
1. In the CLI session, run the following command to generate a private key and a certificate signing request (CSR) in the *rootca* directory. For more information about the OpenSSL `req` command, see the [openssl-req](https://www.openssl.org/docs/man3.1/man1/openssl-req.html) manual page in [OpenSSL documentation](https://www.openssl.org/docs/).
148+
1. In the CLI session, run the following command to generate a certificate signing request (CSR) in the *rootca* directory and a private key in the *rootca/private* directory. For more information about the OpenSSL `req` command, see the [openssl-req](https://www.openssl.org/docs/man3.1/man1/openssl-req.html) manual page in [OpenSSL documentation](https://www.openssl.org/docs/).
149+
150+
> [!NOTE]
151+
> Even though this root CA is for testing purposes and won't be exposed as part of a public key infrastructure (PKI), we recommend that you do not share the private key.
129152
130153
```bash
131154
openssl req -new -config rootca.conf -out rootca.csr -keyout private/rootca.key
@@ -149,48 +172,49 @@ Proc
149172
cd {basedir}
150173
```
151174
152-
1. In the CLI session, run the following commands, one at a time. This step creates the following folder structure and support files for the subordinate CA.
175+
1. In the CLI session, run the following commands, one at a time, replacing the following placeholders with corresponding values.
153176
154-
| Folder or file | Description |
177+
| Placeholder | Description |
155178
| --- | --- |
156-
| subca | The root folder of the subordinate CA. |
157-
| subca/certs | The folder in which CA certificates for the subordinate CA are created and stored. |
158-
| subca/db | The folder in which the database for the subordinate CA is stored. |
159-
| subca/db/index | The index file for the subordinate CA. The `touch` command creates a file without any content, for later use. |
160-
| subca/db/serial | The serial number file for the subordinate CA. The `openssl` command creates a 16-byte random number in hexadecimal format, then stores it in this file. |
161-
| subca/db/crlnumber | A file used to store serial numbers for revoked CA certificates issued by the subordinate CA. The `echo` command pipes a sample serial number, 1001, into the file. |
162-
| subca/private | The folder in which private files, including the private key, for the subordinate CA are stored. |
179+
| {CA_Directory} | The name of the directory for the subordinate CA. For example, `subca`.|
180+
181+
This step creates a folder structure and support files for the subordinate CA similar to that created for the root CA in [Create a root CA](#create-a-root-ca).
163182
164183
```bash
165-
mkdir subca
166-
cd subca
184+
mkdir {CA_Directory}
185+
cd {CA_Directory}
167186
mkdir certs db private
168187
touch db/index
169188
openssl rand -hex 16 > db/serial
170189
echo 1001 > db/crlnumber
171190
```
172191
173-
1. Create a text file named *subca.conf* in the *subca* folder created in the previous step, then copy and save the following OpenSSL configuration settings into that file. The file provides OpenSSL with the values needed to configure your test subordinate CA. For this example, the file configures a subordinate CA named *subca* for the *example.com* domain, using the folders and files created in previous steps. The file also provides configuration settings for:
174-
- The CA policy used by the subordinate CA for certificate Distinguished Name (DN) fields
175-
- Certificate requests created by the subordinate CA
176-
- X.509 extensions applied to root CA certificates, intermediate CA certificates, and client certificates issued by the subordinate CA
192+
1. Create a text file named *subca.conf* in the *subca* folder created in the previous step. Open that file in a text editor, and then copy and save the following OpenSSL configuration settings into that file, replacing the following placeholders with corresponding values.
193+
194+
| Placeholder | Description |
195+
| --- | --- |
196+
| {CA_Name} | The name of the subordinate CA. For example, `subca`.|
197+
| {Domain_Suffix} | The suffix of the domain name for the subordinate CA. For example, `example.com`. |
198+
| {Common_Name} | The common name of the subordinate CA. For example, `Test Subordinate CA`. |
199+
200+
As with the configuration file for your test root CA, the file provides OpenSSL with the values needed to configure your test subordinate CA.
177201
178202
For more information about the syntax of OpenSSL configuration files, see the [config](https://www.openssl.org/docs/manmaster/man5/config.html) master manual page in [OpenSSL documentation](https://www.openssl.org/docs/).
179203
180-
```bash
204+
```xml
181205
[default]
182-
name = subca
183-
domain_suffix = example.com
206+
name = {CA_Name}
207+
domain_suffix = {Domain_Suffix}
184208
aia_url = http://$name.$domain_suffix/$name.crt
185209
crl_url = http://$name.$domain_suffix/$name.crl
186210
default_ca = ca_default
187211
name_opt = utf8,esc_ctrl,multiline,lname,align
188212
189213
[ca_dn]
190-
commonName = "Test Subordinate CA"
214+
commonName = "{Common_Name}"
191215
192216
[ca_default]
193-
home = .
217+
home = ../rootca
194218
database = $home/db/index
195219
serial = $home/db/serial
196220
crlnumber = $home/db/crlnumber
@@ -199,9 +223,9 @@ Proc
199223
RANDFILE = $home/private/random
200224
new_certs_dir = $home/certs
201225
unique_subject = no
202-
copy_extensions = copy
203-
default_days = 365
204-
default_crl_days = 90
226+
copy_extensions = none
227+
default_days = 3650
228+
default_crl_days = 365
205229
default_md = sha256
206230
policy = policy_c_o_match
207231
@@ -240,7 +264,7 @@ Proc
240264
basicConstraints = critical,CA:false
241265
extendedKeyUsage = clientAuth
242266
keyUsage = critical,digitalSignature
243-
subjectKeyIdentifier = hash
267+
subjectKeyIdentifier = hash
244268
```
245269
246270
1. In the CLI session, run the following commands to generate a private key and a certificate signing request (CSR) in the *subca* directory.
@@ -249,23 +273,30 @@ Proc
249273
openssl req -new -config subca.conf -out subca.csr -keyout private/subca.key
250274
```
251275
252-
1. In the CLI session, run the following command to create a self-signed root CA certificate in the *subca* directory. The command applies the `ca_ext` configuration file extensions to the certificate. These extensions indicate that the certificate is for a root CA and can be used to sign certificates and certificate revocation lists (CRLs). The command also signs
276+
1. In the CLI session, run the following command to create an subordinate CA certificate in the *subca* directory. The command applies the `sub_ca_ext` configuration file extensions to the certificate. These extensions indicate that the certificate is for a subordinate CA and can also be used to sign certificates and certificate revocation lists (CRLs). Unlike the root CA certificate, this certificate isn't self-signed. Instead, the subordinate CA certificate is signed with the root CA certificate, establishing a certificate hierarchy similar to what you would use for a public key infrastructure (PKI). The subordinate CA certificate is then used to sign client certificates for testing your devices.
253277

254278
```bash
255-
openssl ca -selfsign -config rootca.conf -in rootca.csr -out rootca.crt -extensions ca_ext
279+
openssl ca -config ../rootca/rootca.conf -in subca.csr -out subca.crt -extensions sub_ca_ext
256280
```
257-
## Step 6 - Create a subordinate CA
258281

259-
This example shows you how to create a subordinate or registration CA. Because you can use the root CA to sign certificates, creating a subordinate CA isn’t strictly necessary. Having a subordinate CA does, however, mimic real world certificate hierarchies in which the root CA is kept offline and a subordinate CA issues client certificates.
282+
## Upload and verify your subordinate CA certificate
283+
284+
After you've created your subordinate CA certificate, you must then upload the certificate to the IoT hub with which you test devices that use client certificates signed by that subordinate CA certificate. When you upload your subordinate CA certificate to your IoT hub, you can set it to verified automatically. The following procedure describes how to upload and automatically verify your subordinate CA certificate to your IoT hub.
285+
286+
1. In the Azure portal, navigate to your IoT hub and select **Certificates** from the resource menu, under **Security settings**.
287+
288+
1. Select **Add** from the command bar to add a new CA certificate.
289+
290+
1. Enter a display name in the **Certificate name** field.
291+
292+
1. Select the certificate file of your subordinate CA certificate to add in the **Certificate .pem or .cer file** field.
293+
294+
1. To automatically verify the certificate, check the box next to **Set certificate status to verified on upload**.
260295
261-
From the *subca* directory, use the configuration file to generate a private key and a certificate signing request (CSR).
296+
:::image type="content" source="media/tutorial-x509-prove-possession/skip-pop.png" alt-text="Screenshot showing how to automatically verify the certificate status on upload.":::
262297
263-
```bash
264-
openssl req -new -config subca.conf -out subca.csr -keyout private/subca.key
265-
```
298+
1. Select **Save**.
266299
267-
Submit the CSR to the root CA and use the root CA to issue and sign the subordinate CA certificate. Specify `sub_ca_ext` for the extensions switch on the command line. The extensions indicate that the certificate is for a CA that can sign certificates and certificate revocation lists (CRLs). When prompted, sign the certificate, and commit it to the database.
300+
If you chose to automatically verify your certificate during upload, your certificate is shown with its status set to **Verified** on the **Certificates** tab of the working pane.
268301
269-
```bash
270-
openssl ca -config ../rootca/rootca.conf -in subca.csr -out subca.crt -extensions sub_ca_ext
271-
```
302+
You now have a

0 commit comments

Comments
 (0)