非対称鍵暗号への導入
非対称鍵暗号(公開鍵暗号)は、現代のデジタルセキュリティの要です。単一の鍵を共有する共通鍵暗号とは異なり、非対称システムは鍵のペアを使用します。暗号化または署名の検証のための公開鍵と、復号または署名のための秘密鍵です。
このガイドでは、従来のRSAから現代の楕円曲線暗号(ECC)への進化を探り、Ed25519、X25519などの標準や、RSA-PSS、HKDFなどの高度なスキームについて解説します。
1. RSA変体:OAEP、PSS、PKCS1-v1.5
RSA(Rivest–Shamir–Adleman)は数十年にわたり業界標準でした。しかし、RSAがどのように実装されるかは、セキュリティにおいて非常に重要です。
RSA-PKCS1-v1.5(レガシー標準)
最も古いパディングスキームです。現在も広く使用されていますが、パディングオラクル攻撃(Bleichenbacher攻撃など)に対して脆弱です。新しいアプリケーションでの使用は一般的に推奨されません。
RSA-OAEP(Optimal Asymmetric Encryption Padding)
暗号化に使用されます。OAEPはFeistelネットワークベースのパディングを追加し、「平文認識」を提供します。これにより、攻撃者が暗号文を修正して平文に関する情報を得ることを防ぎます。
- 推奨: データの暗号化にはPKCS1-v1.5の代わりにRSA-OAEPを使用してください。
RSA-PSS(Probabilistic Signature Scheme)
デジタル署名に使用されます。古いスキームとは異なり、PSSはランダムオラクルモデルにおいて証明可能安全です。署名プロセスにソルトを追加し、決定論的ではなく確率的なものにします。
- 推奨: TLS 1.3などの現代的なプロトコルでは、古いPKCS1-v1.5署名よりもRSA-PSSが要求されるか、強く推奨されています。
2. 楕円曲線暗号(ECC)の深掘り
ECCは、RSAと同じレベルのセキュリティをはるかに小さい鍵で提供します。例えば、256ビットのECC鍵は、約3072ビットのRSA鍵に相当します。
ECDSA(Elliptic Curve Digital Signature Algorithm)
DSA(Digital Signature Algorithm)の楕円曲線版です。
- ECDSA-P256: 最も一般的なNIST曲線です。広くサポートされていますが、NISTパラメータに「バックドア」が潜んでいる可能性を懸念する声もあります。
- ECDSA-P384: より高いセキュリティレベル(極秘レベル)に使用されます。
EdDSAとTwisted Edwards曲線
現代の暗号学はEdDSA(Edwards-curve Digital Signature Algorithm)へと移行しています。
- Ed25519: Curve25519に基づいています。高速かつ高セキュリティを実現するように設計されています。決定論的(署名時に乱数生成器を必要としない)であるため、ECDSAでよく見られる壊滅的な失敗の原因を排除できます。
- Ed448: Ed25519よりもさらに高いセキュリティ(224ビットセキュリティレベル)を提供する「ゴルディロックス」曲線です。
3. 鍵交換プロトコル
安全でないチャネルを通じて、二者間でどのように共有秘密鍵を確立するのでしょうか?
Diffie-Hellman(DH)
最初の鍵交換プロトコルです。今日では、そのほとんどが楕円曲線版に置き換えられています。
ECDH(Elliptic Curve Diffie-Hellman)
- ECDH-P256 / P384: NIST曲線を使用して秘密を確立します。
- X25519: 現代の鍵交換のゴールドスタンダードです。Curve25519を使用したECDH関数です。NIST曲線よりも高速で安全であり、正しく実装するのが容易です。
- X448: X25519のより高セキュリティな対応版です。
4. 鍵導出:HKDF
共有秘密鍵が確立された後(例:X25519経由)、それを直接暗号化鍵として使用すべきではありません。代わりに、**鍵導出関数(KDF)**を使用します。
HKDF-SHA256(HMAC-based Extract-and-Expand KDF)
HKDFは2段階のプロセスに従います:
- Extract: 「生の」共有秘密鍵とオプションのソルトを受け取り、「擬似乱数鍵」(PRK)を生成します。
- Expand: そのPRKを、必要な長さの複数の鍵(例:AES鍵とIV)に変換します。
HKDF-SHA256を使用することで、最終的な鍵が暗号学的に強力で独立していることが保証されます。
5. 比較表
| アルゴリズム | 鍵サイズ(セキュリティ) | パフォーマンス | 標準 | ユースケース |
|---|---|---|---|---|
| RSA 2048 | 112ビット | 低速 | レガシー | 互換性 |
| RSA 3072 | 128ビット | 極めて低速 | 強力 | レガシー/エンタープライズ |
| ECDSA-P256 | 128ビット | 高速 | NIST | 一般的なモバイル/Web |
| Ed25519 | 128ビット | 極めて高速 | 現代的 | 署名に推奨 |
| X25519 | 128ビット | 極めて高速 | 現代的 | 鍵交換に推奨 |
| Ed448 | 224ビット | 中速 | 高セキュリティ | 超高セキュリティシステム |
6. セキュリティ推奨事項:なぜEd25519なのか?
なぜ専門家はRSAやNIST曲線からEd25519へ移行しているのでしょうか?
- サイドチャネル攻撃への耐性: Ed25519の実装は設計上コンスタントタイム(一定時間)であることが多く、タイミング攻撃から保護されます。
- 「運任せ」の乱数排除: ECDSAは署名ごとに新鮮で高品質な乱数を必要とします。RNG(乱数生成器)がわずかでも失敗すると、秘密鍵が復元される可能性があります。Ed25519は決定論的であり、この問題を完全に回避します。
- パフォーマンス: Ed25519は署名と検証において大幅に高速であり、高トラフィックのサーバーにとって重要です。
- 小さな鍵: 32バイトの鍵は、512バイトのRSA鍵よりもQRコード、データベースインデックス、ヘッダーでの取り扱いがはるかに容易です。
7. コード例
Node.js: Ed25519署名
組み込みの crypto モジュールを使用:
const crypto = require('crypto');
// Ed25519鍵ペアの生成
const { privateKey, publicKey } = crypto.generateKeyPairSync('ed25519');
const message = Buffer.from('Hello, Security!');
// 署名
const signature = crypto.sign(null, message, privateKey);
// 検証
const isVerified = crypto.verify(null, message, publicKey, signature);
console.log('署名の検証結果:', isVerified);
Python: X25519鍵交換
cryptography ライブラリを使用:
from cryptography.hazmat.primitives.asymmetric import x25519
# アリス側
alice_private = x25519.X25519PrivateKey.generate()
alice_public = alice_private.public_key()
# ボブ側
bob_private = x25519.X25519PrivateKey.generate()
bob_public = bob_private.public_key()
# 共有秘密の計算
alice_shared = alice_private.exchange(bob_public)
bob_shared = bob_private.exchange(alice_public)
assert alice_shared == bob_shared
print("共有秘密鍵が確立されました!")
8. FAQ:よくある落とし穴
Q: RSA-OAEPとRSA-PSSに同じ鍵を使用できますか?
A: 技術的には可能ですが、強く推奨されません。異なる目的(暗号化と署名)に同じ鍵を使用すると、プロトコル間攻撃を招く可能性があります。常に役割ごとに別々の鍵を使用してください。
Q: Ed25519は耐量子コンピュータですか?
A: いいえ。 RSAや現在のすべてのECCと同様に、Ed25519はショアのアルゴリズムを使用する大規模な量子コンピュータに対して脆弱です。耐量子性については、ML-KEMやML-DSAなどの耐量子計算機暗号(PQC)を検討する必要があります。
Q: なぜHKDFでSHA-256を使用するのですか?
A: SHA-256は高いセキュリティマージンを提供し、世界中でサポートされています。SHA-3やBLAKE2も優れていますが、SHA-256は依然としてHKDF実装の業界標準です。
まとめ
RSAから楕円曲線暗号への移行は、セキュリティと効率の両面で大きな飛躍を意味します。現代的なアプリケーションでは:
- デジタル署名には Ed25519 を使用する。
- 鍵交換には X25519 を使用する。
- 鍵導出には HKDF-SHA256 を使用する。
- レガシーな互換性が厳密に必要な場合にのみ RSA-OAEP/PSS を使用する。
これらの現代的な標準を採用することで、アプリケーションの高速化、安全性の確保、そして最新の暗号学的なベストプラクティスへの準拠を実現できます。