現場のエンジニアへ:暗号化は「魔法」ではない。その脆弱性が組織を殺す
「暗号化しています」という言葉ほど、現場で空虚に響くものはない。SSL/TLSを有効にしているから安全? AESを使っているから大丈夫? そう考えているなら、今すぐ考えを改めた方がいい。
OWASP Top 10の常連である「A02:2021-Cryptographic Failures(暗号化の不備)」は、単なる実装ミスではない。それは、暗号という「技術の皮」を被った、脆弱性に対する無関心そのものだ。今日のインシデントハンドリングの現場では、古いアルゴリズムや不適切な運用が、攻撃者の格好の侵入経路になっている。
今日は、教科書的な説明は抜きにして、実務で明日から「穴」を塞ぐための戦略を話そう。
—
1. 攻撃者はなぜ「暗号化の不備」を狙うのか?
攻撃者が狙うのは、最新のアルゴリズムを数学的に破るような高度な演算ではない。彼らが狙うのは、「設定の不整合」と「実装の怠慢」だ。
例えば、AES-CBCモードで初期化ベクトル(IV)を再利用したり、予測可能なIVを生成したりすれば、ブロック暗号の構造を突いた復号が可能になる。また、RSA-PKCS#1 v1.5のような古いパディング方式を使えば、サイドチャネル攻撃(Bleichenbacher攻撃など)によって、秘密鍵が手元になくても通信を傍受・改ざんできる。
「動けばいい」というコードが、数年後に「組織を崩壊させるトリガー」になる。これが現実だ。
—
2. 実装の正解:AES-GCMへの移行
共通鍵暗号において、今選ぶべきは間違いなく AES-GCM(Galois/Counter Mode)だ。これは機密性(暗号化)だけでなく、認証(改ざん検知)も同時に提供する「認証付き暗号」だからだ。
以下は、Pythonで実装する際のベストプラクティスだ。cryptographyライブラリを使用する。
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# 鍵は環境変数等で厳重に管理すること。ハードコードは論外。
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)
# nonce(IV)は毎回必ず生成し、再利用してはならない。
# nonceは暗号文と一緒に保存/送受信する必要がある。
nonce = os.urandom(12)
data = b"秘匿すべき機密データ"
# 暗号化と同時にタグが生成され、改ざんを自動的に検知する
ciphertext = aesgcm.encrypt(nonce, data, None)
# 復号時、データが改ざんされていれば例外(InvalidTag)が発生する
decrypted_data = aesgcm.decrypt(nonce, ciphertext, None)
ここでのポイント:
nonce(IV)の使い回しは、暗号強度を根底から破壊する。必ずos.urandom(12)を使え。AES-GCMはタグを自動検証するため、わざわざHMACを別途実装して計算量を増やす必要がない。
—
3. Webアプリの盾:NginxでのTLS 1.3強制
Webアプリケーション側の暗号スイートがいくら強固でも、Webサーバーの口(TLS)がガバガバでは意味がない。TLS 1.2以下のレガシーな暗号スイート(3DESやCBCモード)を排除し、TLS 1.3を強制するのが今の鉄則だ。
nginx.conf に以下の設定を投入してほしい。
# TLS 1.2以下を許可せず、TLS 1.3のみを許可する(要件に応じて1.2を許容するならECDHEのみに絞る)
ssl_protocols TLSv1.3;
# 強力な暗号スイートのみを指定
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# サーバー側で暗号スイートの優先順位を決定する
ssl_prefer_server_ciphers on;
# Perfect Forward Secrecy (PFS) の確保
ssl_ecdh_curve secp384r1;
古いブラウザの互換性を気にする声が聞こえてきそうだが、セキュリティチーフとしてはこう答える。「古い暗号しかサポートしないクライアントは、リスクそのものである」。ビジネスの要件と天秤にかけるべきではない。
—
4. 最後に:エンジニアとしての矜持
暗号化の不備を修正することは、コードを書き換えることではない。「何が守るべき資産で、どのリスクが許容できないか」を定義し直す作業だ。
- 鍵管理: 暗号アルゴリズムが最強でも、鍵をGitのコミット履歴に残していたら無意味だ。AWS KMSやHashiCorp Vaultを使い、鍵をコードから分離せよ。
- 脆弱性スキャン:
nmapやtestssl.shを定期的に実行し、自社のサーバーがどのような暗号スイートを提示しているかを可視化せよ。
君たちが書く一行のコードが、数万人のユーザーのプライバシーを守っている。その自覚を持つこと。もし、コードの暗号化方式が「よくわからないけど昔からあったから」という理由で放置されているなら、今すぐ修正チケットを切るべきだ。
セキュリティは「完成」しない。だが、君たちの「意識」一つで、攻撃者の壁は極めて高くできる。健闘を祈る。
コメント