基本情報技術者 2011年 秋期 午前(科目A) 問42
問題文
入力パスワードと登録パスワードを用いて利用者を認証する方法において、パスワードファイルへの不正アクセスによる登録パスワードの盗用防止策はどれか。
選択肢
ア:パスワードに対応する利用者IDのハッシュ値を登録しておき、認証時に入力された利用者IDをハッシュ関数で変換して参照した登録パスワードと入力パスワードを比較する。
イ:パスワードをそのまま登録したファイルを圧縮しておき、認証時に復元して、入力されたパスワードと比較する。
ウ:パスワードをそのまま登録しておき、認証時に入力されたパスワードと登録内容をともにハッシュ関数で変換して比較する。
エ:パスワードをハッシュ値に変換して登録しておき、認証時に入力されたパスワードをハッシュ関数で変換して比較する。(正解)
パスワード保管と認証方法の盗用防止策【午前2 解説】
要点まとめ
- 結論→登録パスワードは平文で保存せず一方向ハッシュのみを保管し、認証時は入力をハッシュ化して比較する方式が適切です。
- 根拠→ハッシュは元に戻せない一方向性を持つため、パスワードファイルが漏洩しても平文そのものの盗用を防げます。
- 差がつくポイント→ハッシュだけでなくソルトやストレッチ(PBKDF2/bcrypt/Argon2)とファイル権限・TLS等の併用で実務上の安全性が高まります。
正解の理由
正解: エ
エは「パスワードをハッシュ値に変換して登録し、認証時に入力パスワードをハッシュ化して比較する」方式を示しています。ファイルに平文パスワードを置かないため、パスワードファイルを不正取得されてもそのままのパスワードが得られず盗用リスクを大幅に下げられます。なお、実務ではソルトの付与やストレッチ(繰り返しハッシュ)、安全なハッシュ関数(bcrypt/Argon2等)を併用します。
エは「パスワードをハッシュ値に変換して登録し、認証時に入力パスワードをハッシュ化して比較する」方式を示しています。ファイルに平文パスワードを置かないため、パスワードファイルを不正取得されてもそのままのパスワードが得られず盗用リスクを大幅に下げられます。なお、実務ではソルトの付与やストレッチ(繰り返しハッシュ)、安全なハッシュ関数(bcrypt/Argon2等)を併用します。
よくある誤解
- ハッシュ化すればそれだけで完全に安全になる:ソルトやストレッチを使わない単純ハッシュはレインボーテーブル攻撃や高速ブルートフォースに弱いです。
- ユーザーIDをハッシュ化すればパスワードが安全になる:IDの扱いは別問題で、パスワードが平文で保存されていれば盗用されます。
- 圧縮すれば保護になる:圧縮はデータ量削減であり暗号化ではないため、盗まれれば復元され平文が露出します。
解法ステップ
- 問題の目的を確認:パスワードファイルへの不正アクセスによる登録パスワードの「盗用防止」。
- 各選択肢がパスワードをファイルに「平文で保存しているか」「ハッシュで保存しているか」を判定。
- 平文保存の選択肢はファイル窃取で即アウト。圧縮・IDハッシュは無関係。
- ハッシュ値のみ保存し、認証時に入力をハッシュ化して比較する方式(エ)が目的に合致する。
選択肢別の誤答解説
- ア:利用者IDをハッシュして参照する仕組みはIDの保護にはなるが、問題は登録パスワードの盗用防止。選択肢文からはパスワードを平文で保存しているように読め、盗用防止になりません。
- イ:パスワードをそのまま保存してファイルを圧縮するだけではセキュリティにならず、盗まれれば復元されます。圧縮は保護機能ではありません。
- ウ:認証時に両方をハッシュして比較するとしても、登録は平文のまま保持しているためファイルが盗まれれば平文が漏洩します。保存方法が誤りです。
- エ:パスワードをハッシュ値で保存し、認証時に入力をハッシュ化して比較する点で正解。平文を保管しないため、ファイル盗難による直接的な盗用を防げます。ただしソルト等の追加対策が推奨されます。
補足コラム
実務上のベストプラクティス:
- ソルト(ランダム値)を各ユーザーに付与してハッシュ化し、ソルトはパスワードハッシュとともに保存する。
- 計算コストを上げるストレッチ(PBKDF2、bcrypt、scrypt、Argon2)を使い高速攻撃を困難にする。
- パスワードファイルへのアクセス権限制御、暗号化バックアップ、通信のTLS保護、異常ログ監視も併用する。
簡単なPython例(PBKDF2でソルト付きハッシュ生成と検証):
import os, hashlib, binascii
def hash_password(password: str, salt: bytes = None, iterations: int = 200_000):
if salt is None:
salt = os.urandom(16)
dk = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, iterations)
return binascii.hexlify(salt).decode(), binascii.hexlify(dk).decode()
def verify_password(stored_salt_hex: str, stored_hash_hex: str, password: str, iterations: int = 200_000):
salt = binascii.unhexlify(stored_salt_hex)
_, candidate_hash = hash_password(password, salt, iterations)
return candidate_hash == stored_hash_hex
# 生成例
salt_hex, hash_hex = hash_password("secret_password")
# 検証例
assert verify_password(salt_hex, hash_hex, "secret_password")
FAQ
Q1: ハッシュと暗号化はどう違いますか?
A1: ハッシュは一方向で元に戻せないことを目的に使い、暗号化は復号鍵があれば元に戻せる双方向の処理です。パスワード保管には一方向ハッシュが基本です。
A1: ハッシュは一方向で元に戻せないことを目的に使い、暗号化は復号鍵があれば元に戻せる双方向の処理です。パスワード保管には一方向ハッシュが基本です。
Q2: ソルトは必須ですか?
A2: はい。ソルトは同じパスワードでもハッシュ値を変化させ、レインボーテーブルや同一パスワードの照合を困難にします。
A2: はい。ソルトは同じパスワードでもハッシュ値を変化させ、レインボーテーブルや同一パスワードの照合を困難にします。
Q3: 圧縮や暗号化は役に立ちますか?
A3: 圧縮はセキュリティ向上になりません。暗号化は保管時の保護には有効ですが、運用で復号が必要な場合は実行時に平文が生成されるためハッシュ方式と用途が異なります。
A3: 圧縮はセキュリティ向上になりません。暗号化は保管時の保護には有効ですが、運用で復号が必要な場合は実行時に平文が生成されるためハッシュ方式と用途が異なります。
Q4: なぜbcryptやArgon2が推奨されるのですか?
A4: これらは設計上ストレッチ(計算コスト調整)とメモリ消費を制御でき、高速GPUブルートフォース攻撃に耐性があります。
A4: これらは設計上ストレッチ(計算コスト調整)とメモリ消費を制御でき、高速GPUブルートフォース攻撃に耐性があります。
関連キーワード: パスワードハッシュ、ソルト、ストレッチ、レインボーテーブル、PBKDF2、bcrypt、Argon2、ハッシュ関数、パスワード保護、鍵導出関数、ファイル権限、TLS

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

