IoTアプリケーションをGoogle Cloudに素早くかつ安全に接続する方法
DigiKeyの北米担当編集者の提供
2019-04-24
Google Cloudなどのエンタープライズレベルのクラウドサービスを通じて、IoTの開発者は、拡張可能な仮想マシンサービスからターンキーの人工知能(AI)アプリケーションに至るまでのさまざまな機能を利用することができます。こうしたサービスの基本的な要件は、IoTデバイスとクラウド間の安全な接続を確立し、維持するために特定のセキュリティ方式を使用することです。しかし、開発者にとっては、適切なセキュリティメカニズムの実装は、遅延が生じるだけでなく、厳しい納期の下で稼働するプロジェクトの設計が複雑化する原因となる可能性があります。
専用のセキュリティICを使用して構築されたMicrochip TechnologyのPIC-IoT WG開発ボードは、Google Cloudに接続するためのターンキーソリューションを実現します。専用のセキュリティICを使用することにより、このキットは、Google Cloudサービスに安全に接続できるIoTの設計の開発を高速化するために設計された包括的なプラットフォームを実現します。この記事では、安全な接続のための主要な要件について説明し、一般的なIoTの設計において、開発者がPIC-IoT WGを使用して、これらの要件をいかに満たせるかを紹介します。
セキュリティの複雑さ
IoTデバイスとリモートホストサーバ間の接続を保護する機能は、IoTアプリケーションと関連のネットワーク接続された企業リソースを全体的に保護する上で欠かせません。これらの機能およびその他の企業規模のシステムにより、リソースに制約があるマイクロコントローラや最小限のメモリで構築されたIoTデバイスでは利用できない機能と性能を実現することができます。センサデータを提供したり、アクチュエータをタイムリーに稼働させたりすることが期待されるシンプルなIoTデバイスの場合、最も基本的なセキュリティアルゴリズムを実装するのに必要な処理要件だけでも、その性質により障壁となってしまう可能性があります。
セキュリティ方式は、防御壁を貫通するには、その防御壁が保護する対象となる資産よりもコストがかかるという基本的原則に依存します。アルゴリズムによるセキュリティ方式の場合、これは、暗号化されたメッセージの復号や認証プロトコルの突破は、計算上も法外になることを表します。アルゴリズムによるセキュリティを突破するには、最低でも、保護されたデータやコミュニケーションチャンネルの価値または適時性を上回る一定レベルのコンピュータリソースと時間が必要になります。したがって、暗号化アルゴリズムでは、秘密鍵が関わる計算集約型の複雑な一連の処理手順の下に価値あるデータを埋め込むことが求められるようになります。たとえば、広く普及している Advanced Encryption Standard(AES)アルゴリズムでは、データが複数の処理ラウンドにかけられ、しかも各ラウンドは、秘密鍵から始まり、バイトの置換、シフト、行列乗算と続く一連の手順で構成されています(図1)。

図1: 復号化を困難かつ事実上不可能にすることを目的として、各種の暗号化アルゴリズムでは意図的に一連の複雑な操作が採用されています。たとえば、AESアルゴリズムにおけるこの手順では、データと秘密鍵から派生したビットが組み合わせられます。(画像提供:ウィキメディア・コモンズ)
AESのような対称暗号アルゴリズムが使用される場合、暗号化されたメッセージの受信側は、同じ秘密鍵を使用してデータを復号化します。一方、非対称アルゴリズムでは1組の鍵が使用されます。1つは秘密鍵で、もう1つは公開鍵です。これにより、計算上複雑になるという代償により共有鍵を使用することに関連するリスクを軽減できます。このアプローチでは、送信側と受信側が公開鍵を交換すると同時に、それぞれの秘密鍵を公開されない状態に維持します。一方の当事者はもう一方の当事者の公開鍵を使用してメッセージを暗号化できます。このメッセージは、相手の秘密鍵を使用しない限り復号することはできません。
保護をさらに強化するために、非対称公開鍵暗号化方式に基づき、さらに高度なアルゴリズムも構築されています。これらのアルゴリズムでは、有効期間がごく短い共有秘密鍵を安全に交換することができます。これにより、特定のメッセージ交換セッションの間のみデータを暗号化します。これらの鍵の交換という重要な特性のため、楕円曲線ディフィーヘルマン(ECDH)などのより高度なアルゴリズムでは、複雑な楕円曲線計算のさらに深い位置に秘密を埋め込みます。Transport Layer Security(TLS)のような認証プロトコルでは、ディフィーヘルマン鍵交換のようなメカニズムと公式な識別方式が組み合わせられています。この方式では、公開鍵と、認証機関(CA)から提供された検証可能なデジタル署名(証明書の信頼性を保証する)を埋め込むデジタル証明書が使用されます。
この短い説明からも分かるとおり、セキュリティ方式は、最終的には秘密鍵に依存する暗号化アルゴリズムとプロトコルの階層が基盤となります。これらの階層はハッカーによる定常的な攻撃対象となりますが、もし、秘密鍵を明らかにできると、セキュリティ構造全体が即座に崩壊してしまいます。
そのため、IoTデバイスのセキュリティでは、ハードウェアベースの安全な鍵の保管が必須要件となります。また、こうしたアルゴリズムとプロトコルの計算上の複雑さから、リソースが限られたマイクロコントローラを複雑な計算から解放することができる、専用の暗号化エンジンが必要です。
ハードウェアベースのセキュリティ
Microchip Technology ATECC608A CryptoAuthentication ICなどの特殊なセキュアエレメントハードウェアデバイスは、秘密を保護し、暗号化アルゴリズムの実行を高速化するのに必要な機能を実現します。特にATECC608Aには、最大で16の鍵を安全に保管するためのオンチップのEEPROM、証明書やその他のデータに加えて、NIST SP 800-90A/B/C対応のランダム数発生器などの必要な機能が用意されています。
ATECC608Aは、安全な保管デバイスであると同時に、対称暗号化用のAESや非対称暗号化用のECDHなどを含めて、多くのアルゴリズムの実行を加速化できます。このデバイスでは、セキュアブートなど、より高レベルのサービスもサポートされます(「暗号化チップを使用してIoTデバイスの設計にセキュアブートを追加」)を参照してください。
こうしたアルゴリズムの実行がオフロードされるという性能上の直接的な利点に加えて、ATECC608Aでのこれらの暗号化エンジン、安全なストレージなどの機能の統合により、セキュリティの別の階層が本質的に実現されることになります。つまり、信頼されないエンティティから鍵が隔離された状態になるということです。これらのエンティティには、セキュリティを考慮して設計されていないマイクロコントローラ、そのマイクロコントローラで実行されるソフトウェア、およびそのソフトウェアを使用する個人などが含まれます。秘密鍵を生成するデバイスの機能により、製造設備や流通施設におけるプロビジョニング時にセキュリティを大幅に強化することができます。
その結果、従来からのソフトウェアベースのセキュリティ方式と比較して、脅威ベクタの数が軽減されます。これにより、効果的なセキュリティ方針の核心となる多層防御が実現されます。
このように、ATECC608Aには機能が包括的に統合されていることから、ハードウェアインターフェースの要件が簡素化されます。このデバイスは、マイクロコントローラのI2Cバスを、Microchip TechnologyのMCP9808などのデジタルセンサのような他のデバイスと共有することもできる、別のI2C周辺機器として機能します(図2)。

図2: Microchip Technology ATECC608A CryptoAuthentication IC(左)では、そのセキュリティ関連の処理のすべてがチップ上で完了するため、他のI2Cデバイス(Microchip TechnologyのMCP9808 I2Cデジタル温度センサ(右側)など)とともに使用するための、シンプルなI2Cハードウェアインターフェースを実現できます。(画像提供:Microchip Technology)
ただし、ソフトウェアレベルでは、ATECC608Aの広範な機能により、インターフェースが複雑になります。Microchip TechnologyのCryptoAuthLibライブラリは、このインターフェースを、CryptoAuthLibアプリケーションプログラミングインターフェース(API)で使用できる直感的な関数呼び出しのセットに抽象化します。このライブラリには、Microchip TechnologyのMPLAB X統合開発環境(IDE)の関連するドライバおよびミドルウェアがバンドルされています。CryptoAuthLib APIおよびドライバは、ATECC608Aを使用したカスタムの設計のための基本的な要素を提供しますが、開発者は、Google Cloudとの安全な接続に必要とされる完全なセキュリティチェーンの実装におけるさらなる課題に直面します。Microchip TechnologyのPIC-IoT WG開発ボードは、そうした障害も解消します。
エンドツーエンドのIoTアプリケーションを開発する
ATECC608AおよびMicrochip Technologyの低コストのPIC24FJ128GA705 16ビットマイクロコントローラを基盤とするPIC-IoTボードは、ワイヤレスのIoTの設計であり、Microchip Technology ATWINC1510 Wi-Fiモジュール、Vishay SemiconductorのTEMT6000X01周囲光センサ、およびMCP9808 I2C温度センサが組み込まれています。さらに、開発者は、利用可能な数百ものMikroElektronika Clickボードとともに用意されたセンサおよびアクチュエータを追加することにより、このハードウェアベースのプラットフォームを簡単に拡張することができます。ソフトウェア開発用に、Microchip Technologyは同社のMPLAB X IDEと、関連のMPLAB Code Configurator(MCC)ラピッドプロトタイピングツールを提供しています。
このボードおよび関連のソフトウェアは、安全な接続経由でIoTセンサデバイスからGoogle Cloudサービスに対して実行される、基本的なエンドツーエンドのIoTアプリケーションを評価するためのターンキープラットフォームを実現します。このキットでは、リソースが限られたIoTデバイスでも相互認証を可能にするために設計された、独自のアプローチが採用されています。このアプローチでは、IoTデバイスは軽量のTLSサービスを使用して接続のGoogle側を認証し、JavaScript Object Notation(JSON)ウェブトークン(JWT)を使用して当該のIoT自体をGoogleのサーバに対して認証することができます(「IoTデバイスをクラウドに安全に接続するための、より簡単なソリューション」を参照してください)。デバイスドライバ、ボード対応のパッケージ、ミドルウェアサービスとともに、Microchip Technologyは、MPLAB開発スイートを介してPIC-IoTボードで使用できるIoTアプリケーションの完全なサンプルの一環として、このアプローチを公開しています。
このサンプルアプリケーションを操作することで、開発者はクラウドアプリケーションだけでなく、主要なクラウドサービスプロバイダがIoTデバイスを自社のクラウドに接続するために提供しているIoT固有のサービスについての経験も得ることができます。たとえば、IoTデバイスはGoogle Cloud IoT Coreを経由してGoogle Cloudのリソースにアクセスします。Google Cloud IoT Coreは、これらデバイスへの接続、デバイスに関連したメタデータの管理などに必要なさまざまなサービスを提供します(図3)。

図3: 他のエンタープライズクラウドプロバイダと同様に、Google Cloudは特殊なサービスであるGoogle Cloud IoT Coreも提供します。Google Cloud IoT Coreは、IoTデバイスとクラウドリソースの統合に伴う固有の要件に対応するように設計されています。(画像提供:Google)
クラウドサービスを使用する
バックエンドでは、Google Cloud IoT Coreにより、デバイスは出版/購読(pub/sub)モデルを使用するデータブローカ経由で、高レベルのGoogle Cloudリソースにアクセスすることができます。フロントエンドでは、IoT Coreは、Hypertext Transfer Protocol(HTTP)またはMessage Queuing Telemetry Transport(MQTT)を使用して、IoTデバイスの接続をサポートするブリッジを提供します。MQTTは国際標準化機構(ISO)の標準メッセージ転送であり、最小限の通信帯域幅およびIoTデバイスリソースで実行されるように設計されています。Microchip TechnologyのPIC-IoTボード用ソフトウェアアプリケーションは、前述のTLS/JWT相互認証方式で保護された、Transmission Control Protocol/Internet Protocol(TCP/IP)ソケット接続で実行されるMQTTの使用を示す実例です。
安全な接続の確立後、ソフトウェアはMQTTを使用してGoogle Cloud IoT Coreサービスと通信し、センサデータをGoogle Cloudへ送信して、クラウドサービスからのコマンドに応答するために使用されるチャンネル(「トピック」)を確立します。GoogleはIoTデバイスのソフトウェアを呼び出して購読を行い、続いてデータを指定されたトピックに/devices/{deviceID}/eventsの形式で送信し、ボードのeventsトピックで、サブトピックのオプションを提供します。デバイス管理機能など、その他のトピックに加えて、GoogleはクラウドからIoTデバイスへコマンドを送信するためのトピックである/devices/{device-id}/commandsを指定します。Googleには、IoTデバイスが任意のサブトピック経由で送信されたコマンドを受信できるようにする、catch-allトピック(/devices/{device-id}/commands/#)も用意されています。
PIC-IoTアプリケーションは、タイマおよびコールバックを基盤とする拡張可能なソフトウェアアーキテクチャを使用した各種の手順を実際に示しています。このアーキテクチャのため、メインモジュール(main.c)で必要なのは、メインルーチン(main())に加えて、送信のためのアプリケーションレベルのルーチン(sendToCloud())および受信(receivedFromCloud())メッセージを指定することだけです。main()ルーチン自体は、初期化ルーチンのペアを呼び出してからタイマスケジューラを実行する無限ループへと入り、ユーザーのルーチンのためのプレースホルダを提供します(リスト1)。
コピー
void receivedFromCloud(uint8_t *topic, uint8_t *payload)
{
char *toggleToken = "\"toggle\":";
char *subString;
if ((subString = strstr((char*)payload, toggleToken)))
{
LED_holdYellowOn( subString[strlen(toggleToken)] == '1' );
}
debug_printer(SEVERITY_NONE, LEVEL_NORMAL, "topic: %s", topic);
debug_printer(SEVERITY_NONE, LEVEL_NORMAL, "payload: %s", payload);
}
// This will get called every 1 second only while we have a valid Cloud connection
void sendToCloud(void)
{
static char json[70];
// This part runs every CFG_SEND_INTERVAL seconds
int rawTemperature = SENSORS_getTempValue();
int light = SENSORS_getLightValue();
int len = sprintf(json, "{\"Light\":%d,\"Temp\":\"%d.%02d\"}", light,rawTemperature/100,abs(rawTemperature)%100);
if (len >0) {
CLOUD_publishData((uint8_t*)json, len);
LED_flashYellow();
}
}
#include "mcc_generated_files/application_manager.h"
/*
Main application
*/
int main(void)
{
// initialize the device
SYSTEM_Initialize();
application_init();
while (1)
{
// Add your application code
runScheduler();
}
return 1;
}
リスト1: PIC-IoTボード向けのこのMicrochip Technologyのサンプルアプリケーションでは、メインループを簡素化して、開発者が独自のサービスおよびアプリケーションルーチンを簡単に追加できるようにする一連のタイマおよびコールバックが使用されます。(コード提供元:Microchip Technology)
この無限ループの前に呼び出されるSYSTEM_Initialize()ルーチンは、クロック、A/Dコンバータ(ADC)、割り込みなどのハードウェアコンポーネントを初期化します。application_init()ルーチンは、CryptoAuthenticationライブラリなどの各種ソフトウェアシステムを初期化し、Wi-Fiおよびクラウド自体へと接続します。その最後のタスクとして、application_init()はMAIN_dataTask()の実行用に100ミリ秒(ms)のタイマを設定します。このタイマが期限切れになり、MAIN_dataTask()が呼び出されると、クラウドへの接続がチェックされて、sendToCloud()が1秒に1回呼び出され、必要に応じたボードのLEDの設定により、アプリケーションの現在の動作ステータスが示されます(リスト2)。次に開発者は、Google CloudでMicrochip Technologyによって指定される、無料のサンドボックスアカウントでセンサ値のディスプレイを表示することができます。
コピー
// This gets called by the scheduler approximately every 100ms
uint32_t MAIN_dataTask(void *payload)
{
static time_t previousTransmissionTime = 0;
// Get the current time.This uses the C standard library time functions
time_t timeNow = time(NULL);
// Example of how to send data when MQTT is connected every 1 second based on the system clock
if (CLOUD_isConnected())
{
// How many seconds since the last time this loop ran? int32_t delta = difftime(timeNow,previousTransmissionTime);
if (delta >= CFG_SEND_INTERVAL)
{
previousTransmissionTime = timeNow;
// Call the data task in main.c
sendToCloud();
}
}
if(shared_networking_params.haveAPConnection)
{
LED_BLUE_SetLow();
}
else
{
LED_BLUE_SetHigh();
}
if(shared_networking_params.haveERROR)
{
LED_RED_SetLow();
}
else
{
LED_RED_SetHigh();
}
if (LED_isBlinkingGreen() == false)
{
if(CLOUD_isConnected())
{
LED_GREEN_SetLow();
}
else
{
LED_GREEN_SetHigh();
}
}
// This is milliseconds managed by the RTC and the scheduler, this return makes the
// timer run another time, returning 0 will make it stop
return MAIN_DATATASK_INTERVAL;
}
リスト2: Microchip TechnologyのPIC-IoTサンプルアプリケーションは、タイマおよびコールバックメカニズムを使用してセンサデータを1秒に1回(CFG_SEND_INTERVAL=1)クラウドに送信し、現在の稼働状態を示すようにボードのLEDを更新します。(コード提供元:Microchip Technology)
クラウドからのコマンドの処理も簡単です。このサンプルアプリケーションは、受信したメッセージを処理するために、receivedFromCloud()などの関連するコールバックルーチンを関連付ける方法を示しています。初期化フェーズの一環として、前述のapplication_init()ルーチンは、Google Cloudの購読プロセスを実行するルーチン(CLOUD_subscribe())を呼び出します。このプロセスの一部として、ソフトウェアは表(imqtt_publishReceiveCallBackTable)を、receivedFromCloud()へのコールバックを使用して更新します(リスト3)。この場合、NUM_TOPICS_SUBSCRIBE=1であるため、このサンプルアプリケーションはconfigトピックを使用してインデックスを表へとハードコードします。ただし、より汎用的なコマンドトピックおよび派生するサブトピックを使用することもできます。
コピー
void CLOUD_subscribe(void)
{
mqttSubscribePacket cloudSubscribePacket;
uint8_t topicCount = 0;
// Variable header
cloudSubscribePacket.packetIdentifierLSB = 1;
cloudSubscribePacket.packetIdentifierMSB = 0;
// Payload
for(topicCount = 0; topicCount < NUM_TOPICS_SUBSCRIBE; topicCount++)
{
sprintf(mqttSubscribeTopic, "/devices/%s/config", deviceId);
cloudSubscribePacket.subscribePayload[topicCount].topic = (uint8_t *)mqttSubscribeTopic;
cloudSubscribePacket.subscribePayload[topicCount].topicLength = strlen(mqttSubscribeTopic);
cloudSubscribePacket.subscribePayload[topicCount].requestedQoS = 0;
imqtt_publishReceiveCallBackTable[0].topic = mqttSubscribeTopic;
imqtt_publishReceiveCallBackTable[0].mqttHandlePublishDataCallBack = receivedFromCloud;
MQTT_SetPublishReceptionHandlerTable(imqtt_publishReceiveCallBackTable);
}
if(MQTT_CreateSubscribePacket(&cloudSubscribePacket) == true)
{
debug_printInfo("CLOUD: SUBSCRIBE packet created");
sendSubscribe = false;
}
}
リスト3: このMicrochip Technologyのサンプルアプリケーションは、コールバックルーチンと受信したMQTTメッセージを開発者が簡単に関連付けられることを示しています。この場合、デフォルトトピックから受信したメッセージ用のコールバックとしてreceivedFromCloud()関数が定義されています。(コード提供元:Microchip Technology)
開発者は、提供されるPIC-IoTハードウェアおよびソフトウェアバンドルを使用して、Google Cloudとの間のデータの送受信に関する各種のシナリオを即時に探求することができます。ATECC608A CryptoAuthenticationデバイスなどのPIC-IoTハードウェアは、Google Cloud IoT Coreおよびこの使用モデルに対応するように事前構成されています。開発者はMPLAB X IDEおよびMPLAB Code Configuratorを簡単に使用して、Google Cloudに安全に接続するように設計されたまったく新しいIoTアプリケーションを変更したり、構築したりすることができます。
まとめ
IoTデバイスとネットワーク化されたリソース間の安全な接続を実現することは、ネットワーク接続されたあらゆるサービス環境に対して重要であると同時に、商用のクラウドサービスを操作するために必要不可欠です。安全な接続のために必要とされるソフトウェアサービスの階層を構築することにより、IoTプロジェクトが大幅に遅延し、リソースに制約があるIoTの設計に悪影響が発生する可能性があります。専用のセキュリティICが組み込まれたMicrochip Technology PIC-IoTなどの開発ボードを使用することにより、開発者は、Google Cloudに安全に接続できるIoTアプリケーションを素早く開発することができます。
免責条項:このウェブサイト上で、さまざまな著者および/またはフォーラム参加者によって表明された意見、信念や視点は、DigiKeyの意見、信念および視点またはDigiKeyの公式な方針を必ずしも反映するものではありません。


