AWS IoT 設(shè)備證書即時注冊
實(shí)現(xiàn)步驟如下:
- 創(chuàng)建 CA 證書并在 AWS IoT Core 上注冊和激活。
- 使用該 CA 證書簽發(fā)設(shè)備證書并安裝在 IoT 設(shè)備上。
- 創(chuàng)建 Lambda 函數(shù)實(shí)現(xiàn)設(shè)備證書在 AWS IoT Core 上的自動注冊。
- IoT 設(shè)備與 AWS IoT Core 的第一次連接。
<span id="first">1.創(chuàng)建 CA 證書并在 AWS IoT Core 上注冊和激活。</span>
a) 我們需要將 CA 證書注冊到 AWS IOT Core。 為了安全,AWS IOT Core 提供了相應(yīng)的審核流程確保你同時持有 CA 證書和對應(yīng)的私鑰。因此,在最終注冊 CA 證書之前,我們還需要按照流程生成一份用于驗(yàn)證 CA 證書和私鑰持有者身份的中間證書(請注意這份證書并不是上面創(chuàng)建的 CA 證書)。從控制臺獲取一個隨機(jī)生成的認(rèn)證碼,這個認(rèn)證碼(紅框內(nèi)的字符串)會和你的賬戶綁定。記錄下這個認(rèn)證碼,很快我們就會用到。



b) 創(chuàng)建私鑰和對應(yīng)的 CA 證書:
$ mkdir cert
$ cd cert
$ openssl genrsa -out CA_Private.key 2048
$ openssl req -x509 -new -nodes -key CA_Private.key -sha256 -days 365 -out CA_Certificate.pem
在創(chuàng)建 CA 證書的過程中,你會被提示輸入如下一些內(nèi)容,將前一步記錄下的認(rèn)證碼填入到 Common Name 中:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section)
Common Name (e.g. server FQDN or YOUR name) []: 5204677abdb93df2e70b247510c263f320351eca18e658d7f435224f6bc0309d
c) 再次使用 OpenSSL 生成用于驗(yàn)證身份的私鑰和證書請求文件(CSR – Certificate Signing Request):
$ openssl genrsa -out Verification_Private.key 2048
$ openssl req -new -key Verification_Private.key -out Verification.csr
在創(chuàng)建 CSR 的過程中,你會被提示輸入如下一些內(nèi)容,將前一步記錄下的認(rèn)證碼填入到 Common Name 中,密碼設(shè)置為空:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section)
Common Name (e.g. server FQDN or YOUR name) []: 5204677abdb93df2e70b247510c263f320351eca18e658d7f435224f6bc0309d
d) 接下來,使用 CA 證書和私鑰,以及上面創(chuàng)建的 CSR 來生成一份用于驗(yàn)證身份的中間證書:
$ openssl x509 -req -in Verification.csr -CA CA_Certificate.pem -CAkey CA_Private.key -CAcreateserial -out Verification.crt -days 365 -sha256
e) 最后,完成 CA 證書的注冊和激活。同時,開啟設(shè)備連接 IoT Core 時設(shè)備證書的自動注冊。



<span id="second">2. 使用該 CA 證書簽發(fā)設(shè)備證書并安裝在 IoT 設(shè)備上。</span>
當(dāng)我們創(chuàng)建并注冊好 CA 證書之后,就可以開始用這個 CA 證書來簽發(fā)設(shè)備證書了,步驟如下。
a) 創(chuàng)建一個設(shè)備證書的私鑰 Device.key 和對應(yīng)的證書請求文件 Device_Certificate.csr:
$ openssl genrsa -out Device.key 2048
$ openssl req -new -key Device.key -out Device_Certificate.csr
b) 使用 CA 證書,CA 證書私鑰和證書請求文件簽發(fā)設(shè)備證書 Device_Certificate.crt:
$ openssl x509 -req -in Device_Certificate.csr -CA CA_Certificate.pem -CAkey CA_Private.key -CAcreateserial -out Device_Certificate.crt -days 365 -sha256
在創(chuàng)建設(shè)備證書的過程中,你會被提示輸入如下一些內(nèi)容,將前一步記錄下的認(rèn)證碼填入到 Common Name 中,密碼設(shè)置為空:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section)
Common Name (e.g. server FQDN or YOUR name) []: 5204677abdb93df2e70b247510c263f320351eca18e658d7f435224f6bc0309d
<span id="third">3. 創(chuàng)建 Lambda 函數(shù)實(shí)現(xiàn)設(shè)備證書在 AWS IoT Core 上的自動注冊。</span>
a) 創(chuàng)建 Lambda 函數(shù),并確保執(zhí)行的角色有IOT所有權(quán)限


輸入以下代碼:
var AWS = require('aws-sdk');
exports.handler = function (event, context, callback) {
// 根據(jù)實(shí)際部署區(qū)域?qū)懭?,在certificateARN一處也是。
var region = "us-east-1";
var accountId = event.awsAccountId.toString().trim();
var iot = new AWS.Iot({
'region': region,
apiVersion: '2015-05-28'
});
var certificateId = event.certificateId.toString().trim();
//這里你可以替換成你想要的topic名稱
var topicName = `JITR/test`;
var certificateARN = `arn:aws:iot:${region}:${accountId}:cert/${certificateId}`;
var policyName = `Policy_${certificateId}`;
//定義Policy并賦予權(quán)限,允許IoT設(shè)備連接,發(fā)布,訂閱和接受消息
var policy = {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iot:Publish",
"iot:Subscribe",
"iot:Connect",
"iot:Receive"
],
"Effect": "Allow",
"Resource": [
"*"
]
}
]
};
/*
創(chuàng)建Policy
*/
iot.createPolicy({
policyDocument: JSON.stringify(policy),
policyName: policyName
}, (err, data) => {
//Ignore if the policy already exists
if (err && (!err.code || err.code !== 'ResourceAlreadyExistsException')) {
console.log(err);
callback(err, data);
return;
}
console.log(data);
/*
附加Policy到設(shè)備證書上
*/
iot.attachPrincipalPolicy({
policyName: policyName,
principal: certificateARN
}, (err, data) => {
//Ignore if the policy is already attached
if (err && (!err.code || err.code !== 'ResourceAlreadyExistsException')) {
console.log(err);
callback(err, data);
return;
}
console.log(data);
/*
激活證書
*/
iot.updateCertificate({
certificateId: certificateId,
newStatus: 'ACTIVE'
}, (err, data) => {
if (err) {
console.log(err, err.stack);
callback(err, data);
} else {
console.log(data);
callback(null, "Success, created, attached policy and activated the certificate " + certificateId);
}
});
});
});
}
b) 創(chuàng)建IOT規(guī)則觸發(fā)Lambda函數(shù)




查詢語句如下:
SELECT * FROM '$aws/events/certificates/registered/#'
<span id="fouth">4. IoT 設(shè)備與 AWS IoT Core 的第一次連接。</span>
進(jìn)入到之前創(chuàng)建的 cert 目錄
$ cd cert
合并 CA 證書和設(shè)備證書到一個新的證書形成有效的證書鏈:
$ cat Device_Certificate.crt CA_Certificate.pem > Device_CA_Certificate.crt
下載 IoT Core 的 CA 證書,保存到cert文件夾,重命名為root-CA.crt,用于設(shè)備去驗(yàn)證 AWS IoT Core 的身份
AmazonRootCA1
執(zhí)行 mosquitto_pub 命令去發(fā)布一個消息到對應(yīng)的 topic 上面,這也是設(shè)備與 IoT Core 的第一次連接。如果你回想一下之前的步驟,到目前為止我們的設(shè)備證書還只存在于設(shè)備上面,并沒有在 IoT Core 上注冊,那么接下來見證奇跡的時刻就要到啦!
$ mosquitto_pub --cafile root-CA.crt --cert Device_CA_Certificate.crt --key Device.key -h xxxxxxxxxxxxxx.iot.us-east-1.amazonaws.com -p 8883 -q 1 -t JITR/test -i anyclientID --tls-version tlsv1.2 -m "Hello" -d
在第一次執(zhí)行這個命令后,你會看到如下的報錯,那么這是為什么呢?
Client anyclientID sending CONNECT
Error: The connection was lost.
實(shí)際上設(shè)備在第一次連接 IoT Core 的時候,設(shè)備證書還沒有注冊,所以 TLS 認(rèn)證會失敗。這個連接動作會發(fā)布一條注冊消息到 "$aws/events/certificates/registered/<caCertificateID>"上面,接下來 Lambda 函數(shù)接收到這個消息后,會完成設(shè)備證書的注冊,附加 Policy,那么我們再次執(zhí)行這個命令就可以成功了。
$ mosquitto_pub --cafile root-CA.crt --cert Device_CA_Certificate.crt --key Device.key -h xxxxxxxxxxxxxx.iot.us-east-1.amazonaws.com -p 8883 -q 1 -t JITR/test -i anyclientID --tls-version tlsv1.2 -m "Hello" -d
輸出如下:
Client anyclientID sending CONNECT
Client anyclientID received CONNACK
Client anyclientID sending PUBLISH (d0, q1, r0, m1, 'JITR/test', ... (5 bytes))
Client anyclientID received PUBACK (Mid: 1)
Client anyclientID sending DISCONNECT
參考資料
https://aws.amazon.com/cn/blogs/iot/just-in-time-registration-of-device-certificates-on-aws-iot/
https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/what-is-aws-iot.html