本記事は学習用です。作成には ChatGPT と GitHub Copilot を使用しています。
1. 導入:概要と目的
サイドチャネル攻撃は、暗号アルゴリズムそのものの数学的性質を破るのではなく、実装や動作環境から漏れる副次的情報(サイドチャネル)を利用して秘密情報を推定する攻撃である。
代表的なサイドチャネルとして、以下が挙げられる。
| サイドチャネル | 説明 |
|---|---|
| 電力消費 | 暗号処理時の電流変化を計測して鍵のビット等を推定する |
| 実行時間 | 処理時間の微小な差から条件分岐などを特定する |
| 電磁波 | 漏洩する電磁放射を解析する |
| 音響 | CPUや電源コイル鳴き、ファン音などの変化を測定する |
| キャッシュ | CPUキャッシュのヒット/ミスを観測してメモリアクセスを推定する |
これらの攻撃は、ハードウェア、組込み機器、クラウド環境、ブラウザ環境など幅広い領域に影響を及ぼす。
2. 背景と動機
AES、RSA、ECC などの暗号アルゴリズムは理論的には安全性が高いが、実装レベルでの物理的・時間的挙動が観測可能であれば、攻撃によって鍵などの秘密情報が復元される可能性がある。
例:RSAのタイミング攻撃
RSAでは、秘密指数によって処理経路が異なるため、演算時間のわずかな差異から秘密指数のビット値を推測できる場合がある。
攻撃者は多数回の暗号処理を観測し、時間の偏りを統計的に解析することで鍵を推定する。
攻撃の成立条件
- 対象デバイスの観測手段(電力計測・時間測定・キャッシュモニタ等)が存在する
- 同一または同種の操作を多数回実行できる
- 統計的手法によりノイズを低減できる
3. 攻撃手法の分類
サイドチャネル攻撃は観測対象によって大きく以下に分類される。
3.1 タイミング攻撃 (Timing Attack)
処理時間の差異を利用する手法。
例:memcmp() が不一致を見つけた時点で早期リターンする実装だと、一致している先頭バイト数が長いほど処理時間が増えるため、時間差から値を推測できる。
int insecure_memcmp(const void *a, const void *b, size_t len) {
const unsigned char *x = (const unsigned char*)a;
const unsigned char *y = (const unsigned char*)b;
for (size_t i = 0; i < len; i++) {
if (x[i] != y[i]) {
return 1; // 先頭からの一致長に依存して時間が変化
}
}
return 0;
}
3.2 電力解析攻撃 (Power Analysis Attack)
暗号演算時の電力消費パターンを解析して秘密情報を推定する。代表的な手法には以下がある。
| 手法 | 概要 |
|---|---|
| SPA (Simple Power Analysis) | 単一の波形から演算パターンを直接観測する |
| DPA (Differential Power Analysis) | 多数の波形を統計処理してビットごとの鍵情報を抽出する |
ICカードやIoT機器などの組込み機器では特に有効であり、電流プローブ等で波形を取得する。
3.3 電磁解析 (Electromagnetic Analysis)
暗号チップから漏れる微弱な電磁放射を測定し、電力解析と同様に情報を抽出する。物理的接触が不要な非接触型攻撃として成立する場合もある。
3.4 キャッシュ攻撃 (Cache Side-Channel Attack)
CPUキャッシュのヒット/ミス状況を観測し、他プロセスのメモリアクセスを推測する攻撃。クラウドやWebブラウザ上で問題化しており、SpectreやMeltdownのようなマイクロアーキテクチャ脆弱性では、キャッシュが情報漏えい経路として悪用される。
Flush+Reload の概念図(Mermaid)
4. 防御手法と対策
サイドチャネルは多様な経路から発生するため、単一の対策では不十分である。主要な防御策を以下に示す。
| 対策手法 | 概要 |
|---|---|
| コンスタントタイム実装 | 処理時間をデータ依存にしない(例:固定時間比較) |
| ノイズ注入 | 電力・時間の変動を意図的に増やし統計解析を困難にする |
| マスキング | 秘密値にランダム値を合成して演算(差分解析を無効化) |
| シールド | 電磁波の漏洩を物理的に遮断する |
| キャッシュ分離・無効化 | 共有キャッシュを避ける設計や分離、フラッシュの徹底 |
安全な比較関数の例
int constant_time_memcmp(const void *a, const void *b, size_t len) {
const unsigned char *x = (const unsigned char*)a;
const unsigned char *y = (const unsigned char*)b;
unsigned char diff = 0;
for (size_t i = 0; i < len; i++) {
diff |= (unsigned char)(x[i] ^ y[i]);
}
return (int)diff; // 0: equal, 非0: not equal(所要時間は一致長に依存しにくい)
}
この関数はすべてのバイトを必ず走査するため、入力データの一致・不一致にかかわらず処理時間が一定になりやすい。
5. 実際の事例
5.1 Kocher のタイミング攻撃(1996)
Paul Kocher が提案した手法で、RSA の復号時間から秘密指数を推定可能であることを実証した。
5.2 DPA(1999)
Kocher、Jaffe、Jun によって示された電力解析攻撃。ICカードを対象に、DES 鍵を数百回程度の計測で抽出することに成功した。
5.3 Spectre / Meltdown(2018)
CPU の投機的実行機構を悪用し、キャッシュ経由で機密情報を漏洩させる脆弱性。クラウド環境を中心に深刻な影響を与えた。
6. 注意点と限界
- 実装依存のため、理論的に安全でも攻撃が成立しうる
- 完全防御は困難で、リスク低減策の積み重ねが重要
- 攻撃実験には法的・倫理的制限が伴うため、研究目的の環境でも法令・倫理の遵守が必須
7. まとめ
サイドチャネル攻撃は、暗号理論を破るのではなく実装の隙を突く攻撃である。ソフトウェア、ハードウェア、クラウドなど様々な層で発生する可能性があり、防御には設計段階からの配慮が不可欠である。定数時間実装、ノイズ注入、マスキング等の対策を組み合わせることで、攻撃成功率を大幅に低減できる。

コメント