はじめに
AWS IoT CoreがサポートするTLS仕様はきちんとドキュメント化されていますし、エンドポイントのCA証明書についてもドキュメントがあります。
また、クライアント証明書についても受け入れられる署名についてドキュメントがあります。
この記事は、上記以外のこまごまとした挙動をまとめたものです。2024/1時点、かつ東京リージョンでこうなっていたというだけなので、いつでも変更される可能性があるものとしてご覧ください(筆者がドキュメントを見落としている可能性もあります)。
また以下の内容は、すべてTLS 1.2前提です。
サーバ証明書の選択
TLS接続を行ったときにエンドポイントが返すサーバ証明書は、RSA鍵のものとECC鍵のものがあります。
どちらを返すかは、ネゴシエートされた暗号スイートで変わります。ECDHEの鍵合意に署名する必要があるからですね。
- TLS_ECDHE_RSA_* 系ならRSA鍵
- TLS_ECDHE_ECDSA_* 系ならECC鍵
クライアントから Signature Algorithm拡張を送りRSAまたはECCに制限することもできますが、これは証明書チェーン全体に影響するので慎重に行う必要があります。
証明書チェーン
中間証明書やルート証明書は、サーバ証明書の鍵タイプと同じ鍵タイプ(サーバ証明書がRSA鍵なら証明機関もRSA鍵,サーバ証明書がECC鍵なら証明機関もECC鍵)になるようです。
証明書チェーンのどの部分が送られるかは、サーバ証明書の鍵タイプで変わります。
RSA鍵
サーバ証明書がRSA鍵の場合、ルート証明書を含む証明書チェーン全体が送られてきます。また、クロスルート証明書(Starfieldのもの)も送られてきます。
ルート証明書はデバイス側で保持するものなので、ちょっと冗長ですね。互換性のためかもしれません。
ECC鍵
サーバ証明書がECC鍵の場合、証明書チェーン内のサーバ証明書と中間証明書のみが送られてきます。
本来送らなければならないものだけが送られてきている形ですね。
デバイス側での対応
クロスルート証明書だけを保持しておけば... と一瞬考えますが,ECC鍵のルート証明機関の証明書は送られてこないので、ECC鍵のサーバ証明書の検証に失敗します。
素直にRSA/ECC両方のルート証明書を保持しておくのが良いです。
鍵合意
暗号スイートのうちTLS_RSA_* 系はサポートされていますが、フォワードセキュリティがありません。証明書の秘密鍵を提出することを強制された事例(lavabitの事例)があり、フォワードセキュリティのない暗号スイートは使わないことが安全です。
また、TLS_DHE_* 系の暗号スイートはECC鍵を利用することができず遅いため、積極的に使う理由はないです。
鍵合意に一時ECDHを使うTLS_ECDHE_* 系の暗号スイートを使うことが良いですが、AWS IoT Coreでは以下のelliptic curveが利用できるようです(Supported Groups拡張を変えて調べました)。
- NIST P-256
- NIST P-384
- NIST P-521
- x25519
おわりに
リソースに制約のある組み込み系で、チューニングに使えそうな部分を見てみました。
証明書は、ECCベースのものを前提につくることが鍵サイズ的にもトラフィック的にもよさそうな感じです。
TLSを扱うとき、暗号アクセラレータ前提だとAES128/256-GCM・NIST P-256あたりがスタンダードだと思います。暗号アクセラレータがないときはTLS1.3でChaCha20-Poly1305・x25519などに変えるとよさそうかなと思います。スループットの比較をしてみたいところです。