セキュリティ
(ポスト量子) 暗号の正しい答え
(Post-Quantum) Cryptographic Right Answers (words.filippo.io)
要約
2026年の暗号技術の動向を踏まえ、開発者向けの「暗号の正しい答え」が更新されました。ポスト量子遷移は2029年までに完了する必要があり、対称暗号は影響を受けませんが、非対称暗号は大きく変化しました。また、LLM(大規模言語モデル)がバグ発見に有効になったことも新たな推奨事項として挙げられています。
全文翻訳
2026年10月12日 (ポスト量子) 暗号の正しい答え
開発者向けの「暗号の正しい答え」を公開することは、今や伝統となっています。Colin Percivalが2009年に始め、Thomas Ptacekが2015年に続き、Latacoraが2018年と2024年に引き継ぎました。更新するには時期尚早に感じるかもしれませんが、多くのことが変わりました。
ポスト量子遷移のタイムラインは2026年初頭に劇的に変化し、2029年までに完了する必要があるというコンセンサスが生まれました。2029年!3年しかありません!
良いニュースは、あなたが聞いたかもしれないこととは異なり、Groverは問題にならないため、対称暗号は大丈夫だということです。悪いニュースは、すべての非対称な答えが2018年と比較して変化し、ほとんどが2024年と比較しても変化したことです。
以下の答えは、特定のコンプライアンス体制に制約されていないことを前提としていますが、ほとんどの場合FIPS 140.1と互換性があります。もしCNSA 2.0のようなより厳格なものをフォローする必要がある場合は、ご自身で判断してください。最後に、2026年のもう一つの大きな変化を覚えておいてください:LLMは今やバグを見つけるのが非常に得意です。
「利用できる最良のモデルからレビューを受ける」は、長年の定番である「メモリセーフな言語を使用する」と共に、今や間違いなく暗号の正しい答えとなっています。
急いでいる人のためのチートシートです:
データを暗号化する:クラウドにいる場合はKMS。それ以外の場合は、ランダムなノンセ(nonce)を使用したXAES-256-GCMまたはXChaCha20Poly1305。数MBを超えるものを暗号化する場合は、Cobblestone-128を使用してください。
対称鍵長:あまり気にしないでください。選ぶ必要がある場合は256ビットの鍵を使用してください。
対称「署名」:HMAC-SHA-256。
ハッシュアルゴリズム:SHA-2はまだ問題ありませんが、必要に応じて実際のマルチハッシュ(SequenceHash)を使用してください。
ランダムID:32バイトのランダムデータ、別名256ビットの乱数。
パスワード処理:Argon2idまたはscrypt。しかし、代わりにパスキーを検討しましたか?
鍵交換:X25519+ML-KEM-768を安全で標準的なプロトコルで使用してください。
非対称暗号化:HPKE(MLKEM768-X25519、別名X-Wing、HKDF-SHA256、AES-128-GCM)またはPQ鍵を使用したage。
非対称署名:ML-DSA-44。
ウェブサイトまたはクライアントサーバーアプリケーションのセキュリティ:クラウドにいる場合は、そのALB/NLBを使用してください。それ以外の場合は、rustls、Goのcrypto/tls、BoringSSL、AWS-LC、またはs2n-tlsと人気のある更新されたACMEクライアントを使用してください。
オンラインバックアップ:長いランダムパスワードを使用したrestic。
それでは詳しく見ていきましょう。
データを暗号化する
クラウドにいる場合はKMS。それ以外の場合は、ランダムなノンセを使用したXAES-256-GCMまたはXChaCha20Poly1305。数MBを超えるものを暗号化する場合は、Cobblestone-128を使用してください。
Percival, 2009: AES-CTRとHMAC。
Ptacek, 2015: NaCl/libsodiumのデフォルト、またはChaCha20Poly1305、またはAES-GCM。
Latacora, 2018: KMS、またはXSalsa20+Poly1305。
Latacora, 2024: KMS、またはNaClのsecretbox、またはXChaCha20Poly1305。
LatacoraがクラウドのKMSを使用する理由と時期についての説明は依然として堅実なので、そこから始めてください。ローカルで暗号化する場合、ノンセの追跡や暗号化したメッセージの数について心配する必要がないAEAD(Authenticated Encryption with Associated Data)を使用したいので、少なくとも128ビットのランダムなノンセが必要です。
NaCl/libsodiumのsecretboxは、あまり一般的でないAE構成(XSalsa20+Poly1305)の薄いラッパーにすぎないため、代わりにXAES-256-GCMまたはXChaCha20Poly1305を推奨します。前者は標準的なKDFとAES-GCMの効率的な合成であり、拡張ノンセAEADとしてパッケージ化されているため、ライブラリがその名前で提供していなくても、KDFとAES-GCMのAPIから組み立てることができます。
ランダムなノンセを使用した通常のAES-GCMとChaCha20Poly1305は、1つの鍵で10億メッセージを超えることはないと確実にわかっている場合にのみOKです。AES-GCM-SIVも良いAEADの選択肢ですが、どこでも利用できるとは限りません。さらに新しいオプションの中には鍵コミットメントのような良い特性を持つものもありますが、まだ一般的ではありません。
AEADを使用しているので、追加データにコンテキスト(例えば、暗号化しているユーザーIDやプロトコルのバージョン)を含めることを検討してください。復号時に確実にわかっている、秘密ではないものすべてです。
大きなメッセージの処理方法が非常に重要です。KMSはこれを解決してくれません。1つの大きなメッセージをAEADに渡さないでください。そうしないと、復号時に認証する前に平文を処理または保存する必要が生じる可能性があります。認証されていないストリーム暗号は絶対にしないでください。
代わりに、STREAM(ストリーム暗号ではなく、ストリームでAEADを使用する方法です…わかっています、ひどい名前です)を使用する必要があります。多くのオプションがありますが、多すぎます。そして残念ながら、コンセンサスとなる答えはありません。Tinkには1つ、libsodiumには1つ、AWS Encryption SDKには1つ、FLOEは1つ、ageは1つ、そしてリストは続きます。
私はCobblestone-128を推奨します。これはTLSから派生したSTREAMバリアントで、pyca/cryptographyで利用可能であり、まもなくGoの標準ライブラリにも(そしてそれまではfilippo.io/cobblestoneで)利用可能になります。
避けるべきもの:認証されていないモード(CBC、CTR、生のストリーム暗号)、暗号化するメッセージの数を注意深く考えていない限り、ランダムな96ビットノンセ、独自のAEAD構成を作成すること。
対称鍵長
あまり気にしないでください。選ぶ必要がある場合は256ビットの鍵を使用してください。
Percival, 2009: 256ビットAES鍵。
Ptacek, 2015: 256ビット鍵。
Latacora, 2018: 256ビット鍵。
Latacora, 2024: 256ビット鍵。
Groverは実際には問題ではなく、128ビットの総当たり攻撃は存在しないことを覚えておいてください。それでも、256ビットの鍵はマルチターゲット攻撃を排除できるので、それは良いことです。しかし、これに基づいて他の決定をしないでください。例えば、推奨されるCobblestoneスイートは128ビットの鍵を使用していますが、これはマルチターゲット攻撃の注意深い分析があるため問題ありません。同様に、TLSライブラリのデフォルトの暗号スイート設定を変更して256ビットの鍵を強制しないでください。必要ありません。
AES-256はAES-128よりも遅いですが、Rijndaelは鍵サイズによってラウンド数が決まるためですが、これは実際には問題にならないでしょう。
避けるべきもの:128ビットまたは256ビット以外のもの、鍵のサイズについて心配しすぎること、均一でない鍵(例えば、パスワードやASCII16進数文字列を直接鍵として使用すること)。
対称「署名」
HMAC-SHA-256。
Percival, 2009: HMAC。
Ptacek, 2015: HMAC。
Latacora, 2018: HMAC。
Latacora, 2024: HMAC。
HMACは素晴らしいです。ただし、バイトの正確な文字列を認証し、再計算する必要のあるものではないことを常に確認することで、正規化やパーサーのアライメントのバグを回避するように注意してください。
良い例: { "inner": "{\"foo\":123}", "hmac": "MbPsZq7QGCllJgDnSSy/cyM10HjqiVu35UO7yyY5d3w=" }
HMACを確認してから、{"foo":123}のみを処理、保存、または転送します。
悪い例: { "foo": 123, "hmac": "MbPsZq7QGCllJgDnSSy/cyM10HjqiVu35UO7yyY5d3w=" }
KMACまたはキー付きBLAKE3は、それらの基になるハッシュを使用する理由がすでにある場合に使用できます。HMAC-SHA-512も問題ありません。
タグは専用の定数時間関数で比較することを忘れないでください。
避けるべきもの:独自のYoloMACを作成すること、暗号化されたハッシュ、Poly1305やGMACのようなスタンドアロンのワンタイムMAC。
ハッシュアルゴリズム
SHA-2はまだ問題ありませんが、必要に応じて実際のマルチハッシュを使用してください。
Percival, 2009: SHA-256 (SHA-2)、SHA-3を計画。
Ptacek, 2015: SHA-2。
Latacora, 2018: SHA-2。
Latacora, 2024: SHA-2。
最良の選択肢は、利用可能であれば、依然としてSHA-512/256であり、これは長さ拡張攻撃に対して脆弱ではありません。それ以外の場合は、SHA-256とSHA-512の両方が問題ありません。
SHA-3は不要です(SHA-2が問題ないため)し、遅いですが、間違っているわけではありません。ML-KEMとML-DSAのためにすでにKeccak (SHA-3) を使用しており、それをハッシュに使用したい場合は、SHAKE128から32バイトを抽出してください。
BLAKE2は最近では奇妙な選択肢です。BLAKE3は非常に高速ですが、複雑で一般的ではないため、使用する良い理由と実装を信頼する良い理由が必要です。
マルチハッシュは、複数のものを一度にハッシュする必要がある場合です。例えば、行の複数の列、またはファイルの内容と共にファイル名などです。これは見た目よりも微妙なので、SHA-2でSequenceHashを使用するか、SHA-3でTupleHash (SP 800-185) を使用してください。
避けるべきもの:SHA-1、MD5、その他のすべてのハッシュ関数、独自のマルチハッシュを作成すること、暗号学者が衝突が懸念事項ではないと伝えない限り、256ビット未満に切り捨てること。
ランダムID
32バイトのランダムデータ、別名256ビットの乱数。
Percival, 2009: 256ビット乱数。
Ptacek, 2015: 256ビット乱数。
Latacora, 2018: 256ビット乱数。