セキュリティ

暗号化

データを第三者に読めなくする処理。

概要

暗号化(Encryption)とは、データを特定のアルゴリズムと鍵を使用して変換し、正しい鍵を持つ者のみが元のデータ(平文)に復元できるようにする技術である。通信の盗聴、ストレージへの不正アクセス、データの漏洩を防ぐために使用される。

情報セキュリティの三要素(CIA: Confidentiality / Integrity / Availability)の「機密性(Confidentiality)」を実現する核心技術である。組み込みシステムでは、通信の暗号化(TLS)、ストレージの暗号化(フラッシュ暗号化)、ファームウェアの暗号化など多くの場面で不可欠となっている。

暗号化は鍵の方式によって「共通鍵暗号」と「公開鍵暗号」に大別され、それぞれ異なる特性と用途を持つ。


歴史・背景

暗号の歴史は古代ローマのカエサル暗号まで遡るが、現代の電子暗号技術は次のマイルストーンで発展した。

  • DES(1977年): NIST(当時の NBS)が標準化した最初の現代的共通鍵暗号。56bit 鍵のため、現在は安全でない。
  • RSA(1978年): 公開鍵暗号の実用的な実装として Rivest・Shamir・Adleman が発表。インターネットセキュリティの基盤となった。
  • AES(2001年): NIST が DES の後継として Rijndael アルゴリズムを標準化。現在最も広く使われる共通鍵暗号。
  • ECC(楕円曲線暗号): 1985 年に理論提案、2000 年代以降に実用化。RSA より短い鍵で同等のセキュリティを実現し、組み込み向けに普及。
  • NIST PQC(2022年): 量子コンピュータへの耐性を持つ「耐量子暗号(Post-Quantum Cryptography)」の標準化が始まり、CRYSTALS-Kyber、CRYSTALS-Dilithium などが選定された。

技術仕様

主要な暗号アルゴリズム一覧

カテゴリアルゴリズム鍵長特徴推奨度
共通鍵(対称)AES-128128 bit高速、ハードウェア支援あり推奨
共通鍵(対称)AES-256256 bitより高いセキュリティ高セキュリティ向け
共通鍵(対称)ChaCha20256 bitソフトウェア実装に最適推奨
公開鍵(非対称)RSA-20482048 bit広く普及互換性重視
公開鍵(非対称)ECDH P-256256 bit省電力、小コード推奨
ハッシュSHA-256256 bit 出力整合性確認推奨
ハッシュSHA-3 / Keccak256〜512 bitより新しい設計今後主流
認証付き暗号AES-GCM128/256 bit暗号化+認証を同時推奨
認証付き暗号ChaCha20-Poly1305256 bitソフトウェア向け推奨

AES の動作モード

┌────────────────────────────────────────────────────────┐
│ AES の主要動作モード                                     │
├────────┬───────────────┬────────────────────────────────┤
│ ECB    │ 最も単純      │ 危険!同じ平文→同じ暗文       │
│ CBC    │ 連鎖ブロック  │ IVが必要、並列化不可           │
│ CTR    │ カウンタモード│ 並列化可能、IV管理が重要       │
│ GCM    │ 認証付き暗号  │ 暗号化+整合性検証を同時実現    │
│ CCM    │ 小型向けGCM   │ IoT/BLE 向け、メモリ効率が良い │
└────────┴───────────────┴────────────────────────────────┘

動作原理

AES-GCM(認証付き暗号)の仕組み

現代の暗号化では、データの秘匿性(暗号化)と完全性(改ざん検知)を同時に実現する AEAD(Authenticated Encryption with Associated Data)が推奨される。

入力: 平文 P, 鍵 K, Nonce(IV) N, 追加認証データ AAD

        [AES-CTR モードで平文を暗号化]

         暗号文 C が生成される

        [GHASH で認証タグ T を計算]
         (C と AAD のハッシュ)

出力: 暗号文 C + 認証タグ T (16 bytes)

復号側: C + T → AES-CTR で復号 → GHASH で T' 計算 → T == T' なら正常

C 言語での AES-GCM 実装例(Mbed TLS 使用)

#include "mbedtls/gcm.h"
#include <string.h>

#define KEY_LEN   16  /* AES-128: 16 bytes */
#define TAG_LEN   16  /* GCM 認証タグ: 16 bytes */
#define IV_LEN    12  /* GCM IV: 12 bytes が推奨 */

int encrypt_data(const uint8_t *key,
                 const uint8_t *iv,
                 const uint8_t *plaintext, size_t pt_len,
                 uint8_t *ciphertext,
                 uint8_t *tag) {
    mbedtls_gcm_context gcm;
    int ret;

    mbedtls_gcm_init(&gcm);

    /* 鍵のセット */
    ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES,
                              key, KEY_LEN * 8);
    if (ret != 0) goto exit;

    /* 暗号化 */
    ret = mbedtls_gcm_crypt_and_tag(
        &gcm,
        MBEDTLS_GCM_ENCRYPT,
        pt_len,          /* 平文サイズ */
        iv, IV_LEN,      /* 初期化ベクタ */
        NULL, 0,         /* 追加認証データ(なし) */
        plaintext,       /* 入力平文 */
        ciphertext,      /* 出力暗号文 */
        TAG_LEN,         /* タグサイズ */
        tag              /* 出力認証タグ */
    );

exit:
    mbedtls_gcm_free(&gcm);
    return ret;
}

int decrypt_data(const uint8_t *key,
                 const uint8_t *iv,
                 const uint8_t *ciphertext, size_t ct_len,
                 const uint8_t *tag,
                 uint8_t *plaintext) {
    mbedtls_gcm_context gcm;
    int ret;

    mbedtls_gcm_init(&gcm);
    ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES,
                              key, KEY_LEN * 8);
    if (ret != 0) goto exit;

    /* 復号と認証タグ検証を同時実施 */
    ret = mbedtls_gcm_auth_decrypt(
        &gcm,
        ct_len,
        iv, IV_LEN,
        NULL, 0,
        tag, TAG_LEN,
        ciphertext,
        plaintext
    );
    /* ret == MBEDTLS_ERR_GCM_AUTH_FAILED なら改ざんあり */

exit:
    mbedtls_gcm_free(&gcm);
    return ret;
}

ハードウェア AES アクセラレータの活用

多くの組み込み SoC は AES ハードウェアアクセラレータを内蔵している。

/* STM32 CRYP ペリフェラルを使った AES 暗号化 */
#include "stm32h7xx_hal.h"

CRYP_HandleTypeDef hcryp;
CRYP_ConfigTypeDef conf;

void hw_aes_gcm_init(const uint8_t *key) {
    conf.DataType      = CRYP_DATATYPE_8B;
    conf.KeySize       = CRYP_KEYSIZE_128B;
    conf.pKey          = (uint32_t *)key;
    conf.Algorithm     = CRYP_AES_GCM;
    conf.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
    HAL_CRYP_Init(&hcryp);
}

/* ハードウェアで暗号化(CPU 負荷が大幅に低下) */
HAL_CRYP_Encrypt(&hcryp, (uint32_t *)plaintext, pt_words,
                 (uint32_t *)ciphertext, HAL_MAX_DELAY);

ESP32 でのフラッシュ暗号化

# ESP-IDF でのフラッシュ暗号化有効化(sdkconfig)
# CONFIG_FLASH_ENCRYPTION_ENABLED=y
# CONFIG_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y  # 開発用
# CONFIG_FLASH_ENCRYPTION_MODE_RELEASE=y      # 本番用

# CLI での確認
# espsecure.py digest_private_key --keyfile key.pem
# esptool.py --chip esp32 get_security_info

用途・ユースケース

通信の暗号化

TLS/DTLS を使ったクラウドとの通信、BLE の AES-CCM/AES-GCM による無線通信暗号化、LoRaWAN の AES-128 セッション鍵による通信暗号化など。

ストレージの暗号化

フラッシュメモリ上のデータ暗号化(ESP32 フラッシュ暗号化、STM32 TZEN/OTFDEC)、EEPROM に保存する設定値の暗号化、SDカード上のログデータ暗号化。

ファームウェアの暗号化

ファームウェアの知的財産(IP)保護のために、配布するファームウェアイメージを暗号化する。デバイス固有の鍵で復号するため、他のデバイスには移植できない。

鍵交換プロセス

ECDH(楕円曲線ディフィー・ヘルマン)を使って安全に共通鍵を交換し、その後 AES-GCM で通信を暗号化するハイブリッド暗号化が標準的なパターンである。


実装・開発のポイント

組み込み向け暗号ライブラリの選択

ライブラリ特徴適用プラットフォーム
Mbed TLSARM 製、軽量、FOSSARM Cortex-M/A
wolfSSL / wolfCrypt小フットプリント、FIPS 対応各種 MCU
tinycrypt超軽量、最小機能超小型 MCU
OpenSSL高機能、サイズ大Linux(MPU)
libsodium使いやすい API、高セキュリティLinux(MPU)

よくある実装ミス

NG: 固定 IV(Nonce)の使用
    → AES-GCM で同じ鍵・同じ IV を使うと鍵が漏洩する

NG: ECB モードの使用
    → 同じ平文ブロックが同じ暗号文になり、パターンが漏洩

NG: 自作暗号アルゴリズム
    → 必ず標準化されたアルゴリズムを使う

NG: 鍵をソースコードにハードコード
    → 解析により簡単に抽出される

OK: 毎回ランダムな IV を生成
OK: AES-GCM / ChaCha20-Poly1305 などの AEAD を使う
OK: 鍵は SE / TPM / OTP に保管

乱数生成の重要性

暗号の強度は乱数の品質に依存する。組み込みでは True Random Number Generator(TRNG)ハードウェアを必ず使用する。

/* STM32 TRNG からの乱数取得 */
uint32_t random_number;
HAL_RNG_GenerateRandomNumber(&hrng, &random_number);

/* AES-GCM IV 生成 */
uint8_t iv[12];
for (int i = 0; i < 3; i++) {
    uint32_t r;
    HAL_RNG_GenerateRandomNumber(&hrng, &r);
    memcpy(iv + i * 4, &r, 4);
}

他技術との比較

用途技術説明
秘密性の確保暗号化(本項)データを第三者に読ませない
真正性・完全性ファームウェア署名改ざん・なりすましを検知
鍵の安全な保管セキュアエレメント / TPM鍵を物理的に保護
通信路の保護TLS/DTLS暗号化+認証を組み合わせたプロトコル
鍵の配布公開鍵暗号 / PKI安全な鍵交換の仕組み

暗号化はセキュリティの「部品」であり、単体では完全な保護を提供しない。鍵管理、認証、アクセス制御などと組み合わせた「セキュリティアーキテクチャ」として設計することが重要である。

関連用語

参考リンク