Pythonのパスワード管理を安全に!passlibライブラリ徹底解説 🔑

プログラミング

堅牢なパスワードハッシュ化を簡単に実装するためのガイド

Webアプリケーションやサービスを開発する上で、ユーザーのパスワードを安全に管理することは非常に重要です。平文(そのままの文字列)でパスワードをデータベースに保存することは、セキュリティ上、絶対に避けるべきです。万が一データベースが漏洩した場合、ユーザーの認証情報が悪用されるリスクが高まります。

そこで登場するのが「パスワードハッシュ化」です。ハッシュ化とは、元のデータを不可逆な固定長のデータ(ハッシュ値)に変換する技術です。Pythonには標準で hashlib というハッシュ化ライブラリがありますが、これは汎用的なハッシュ関数を提供するもので、パスワード専用の機能(ソルトの自動生成やストレッチング回数の管理など)は別途実装する必要があります。

ここで passlib の出番です。passlibは、Pythonのための包括的なパスワードハッシュ化ライブラリであり、安全なパスワード管理に必要な機能を簡単に利用できるように設計されています。最新の推奨アルゴリズムから、レガシーなシステムとの互換性のための古いアルゴリズムまで、30種類以上のハッシュスキーマをサポートしています。

ポイント💡: passlibを使えば、複雑なパスワードハッシュ化のロジックを自分で実装する手間が省け、より安全で信頼性の高いパスワード管理を効率的に実現できます。

passlibは、単にパスワードをハッシュ化するだけでなく、パスワード管理を容易にするための多くの機能を提供します。

  • 豊富なアルゴリズムサポート: bcrypt, scrypt, Argon2, PBKDF2, SHA-Crypt系など、30種類以上のパスワードハッシュアルゴリズムに対応しています。これにより、セキュリティ要件や既存システムとの互換性に応じて最適なアルゴリズムを選択できます。
  • 簡単なAPI: シンプルで直感的なAPIを提供しており、ハッシュ化と検証のプロセスを数行のコードで実装できます。パスワードセキュリティに詳しくない開発者でも容易に利用可能です。
  • CryptContextによる柔軟な設定: CryptContext オブジェクトを使用することで、使用するハッシュアルゴリズム、デフォルトのアルゴリズム、ストレッチング回数(コストパラメータ)、ソルトの長さなどを柔軟に設定できます。
  • ハッシュの自動識別と検証: 保存されているハッシュ文字列から、使用されているアルゴリズムを自動的に識別し、適切な方法で検証を行います。
  • ハッシュの移行サポート: 古い、または推奨されなくなったアルゴリズムでハッシュ化されたパスワードを、ユーザーのログイン時に自動的に新しい推奨アルゴリズムで再ハッシュ化する機能(ハッシュマイグレーション)をサポートします。これにより、システムのセキュリティレベルを段階的に向上させることが可能です。
  • 設定の外部化: パスワードハッシュ化ポリシー(使用アルゴリズム、パラメータなど)をコードから分離し、設定ファイルとして管理できます。
  • Unicodeサポート: UTF-8エンコーディングを適切に処理し、非ASCII文字を含むパスワードにも対応します(ただし、互換性のために正規化が推奨されます)。
  • クロスプラットフォーム: さまざまなOSで動作するように設計されています。

注意点

一部のアルゴリズム(bcrypt, Argon2, scryptなど)は、追加のライブラリ(bcrypt, argon2-cffi, scryptなど)が必要になる場合があります。

passlibを使い始めるのは非常に簡単です。まずはpipを使ってインストールします。

pip install passlib

特定のアルゴリズム(例えばbcryptやArgon2)を使用したい場合は、追加の依存関係も一緒にインストールすると便利です。

# bcrypt を使う場合
pip install "passlib[bcrypt]"

# Argon2 を使う場合
pip install "passlib[argon2]"

# 複数のアルゴリズムを使う場合
pip install "passlib[bcrypt,argon2]"

パスワードのハッシュ化

passlibを使ってパスワードをハッシュ化する最も簡単な方法は、特定のハッシュアルゴリズムの hash() メソッドを使用することです。ここでは、推奨されるアルゴリズムの一つである pbkdf2_sha256 を例にとります。

from passlib.hash import pbkdf2_sha256

# パスワードをハッシュ化 (ソルトは自動生成されます)
password = "mysecretpassword"
hashed_password = pbkdf2_sha256.hash(password)

print(f"元のパスワード: {password}")
print(f"ハッシュ化されたパスワード: {hashed_password}")

# 出力例 (実行ごとにソルトが異なるため、ハッシュ値も変わります):
# 元のパスワード: mysecretpassword
# ハッシュ化されたパスワード: $pbkdf2-sha256$29000$randomsaltstringexample$derivedkeyexample...

hash() メソッドは、自動的に安全なランダムソルトを生成し、適切なデフォルトのストレッチング回数(計算コスト)でパスワードをハッシュ化します。生成されたハッシュ文字列には、アルゴリズム、ストレッチング回数、ソルト、そして実際のハッシュ値(ダイジェスト)が含まれています。この文字列全体をデータベースに保存します。

パスワードの検証

ユーザーがログインしようとするとき、入力されたパスワードがデータベースに保存されているハッシュと一致するかを検証する必要があります。これには verify() メソッドを使用します。

from passlib.hash import pbkdf2_sha256

# データベースから取得したハッシュ値 (上記の例で生成したもの)
stored_hash = "$pbkdf2-sha256$29000$randomsaltstringexample$derivedkeyexample..."

# ユーザーが入力したパスワード
input_password_correct = "mysecretpassword"
input_password_wrong = "wrongpassword"

# 正しいパスワードで検証
is_correct = pbkdf2_sha256.verify(input_password_correct, stored_hash)
print(f"'{input_password_correct}' は正しいか?: {is_correct}") # True

# 間違ったパスワードで検証
is_wrong = pbkdf2_sha256.verify(input_password_wrong, stored_hash)
print(f"'{input_password_wrong}' は正しいか?: {is_wrong}") # False

verify() メソッドは、提供された平文パスワードを、ハッシュ文字列に含まれるソルトとパラメータ(ストレッチング回数など)を使ってハッシュ化し、結果がハッシュ文字列内のダイジェストと一致するかどうかを確認します。

重要🛡️: 検証プロセスでは、データベースに保存されているハッシュ値を復号(元のパスワードに戻すこと)はしません。入力されたパスワードを同じ方法でハッシュ化し、結果を比較するだけです。これが一方向性の特徴です。

個別のハッシュアルゴリズムを直接使うこともできますが、実際のアプリケーションでは、複数のアルゴリズムをサポートしたり、パスワードポリシー(デフォルトアルゴリズム、パラメータ設定、非推奨アルゴリズムなど)を一元管理したりする必要が出てくることがよくあります。このような場合に非常に役立つのが passlib.context.CryptContext クラスです。

CryptContext は、パスワードハッシュ化に関する設定と操作をカプセル化するオブジェクトです。これにより、以下のような利点が得られます。

  • 設定の明確化と可読性の向上
  • 複数のハッシュアルゴリズムの同時サポート
  • デフォルトアルゴリズムとパラメータの指定
  • 非推奨アルゴリズムの設定とハッシュの自動移行
  • 設定の外部ファイルからの読み込み

CryptContextの作成と設定

CryptContext は、schemes パラメータで使用するアルゴリズムのリストを指定して初期化します。また、default パラメータで新規パスワードのハッシュ化に使用するデフォルトのアルゴリズムを指定したり、deprecated パラメータで非推奨にするアルゴリズムを指定したりできます。

from passlib.context import CryptContext

# CryptContext オブジェクトを作成
# schemes: サポートするアルゴリズムのリスト (推奨されるものを優先的に記述)
# default: 新規ハッシュ化に使用するデフォルトアルゴリズム
# deprecated: "auto" を指定すると、schemesリスト内でdefaultより前にあるものは自動的に非推奨扱いになる
pwd_context = CryptContext(
    schemes=["bcrypt", "sha256_crypt", "argon2", "pbkdf2_sha256"], # bcryptを最新、sha256_cryptを次に推奨
    default="bcrypt", # 新規パスワードはbcryptでハッシュ化
    deprecated=["sha256_crypt"], # 明示的にsha256_cryptを非推奨にすることも可能 (autoと併用も可)
    # 特定アルゴリズムのパラメータ設定 (例: bcryptのroundsを増やす)
    bcrypt__rounds=12, # デフォルトは12だが、明示的に指定
    # pbkdf2_sha256__rounds=60000, # 必要に応じて他のアルゴリズムのパラメータも設定可能
)

# アプリケーション固有の名前でインポートすることも推奨される
# from myapp.security import pwd_context

上記の例では、bcrypt, sha256_crypt, Argon2, PBKDF2-SHA256 をサポートし、新規パスワードはbcryptでハッシュ化します。また、sha256_cryptは非推奨として扱われます(deprecated="auto" でも同様の効果)。bcrypt__rounds=12 のように、アルゴリズム名__パラメータ名 という形式で、各アルゴリズムのデフォルトパラメータを上書きすることもできます。

CryptContextを使ったハッシュ化と検証

CryptContext オブジェクトを使えば、ハッシュ化と検証がさらに簡単になります。

# CryptContextオブジェクトは上記で作成済みとする

# パスワードのハッシュ化 (デフォルトアルゴリズム(bcrypt)が使用される)
password = "anothersecret"
hashed_password = pwd_context.hash(password)
print(f"Bcryptでハッシュ化: {hashed_password}")

# パスワードの検証 (ハッシュ文字列からアルゴリズムを自動識別して検証)
is_correct = pwd_context.verify(password, hashed_password)
print(f"検証結果 (bcrypt): {is_correct}") # True

# 別のアルゴリズムでハッシュ化されたパスワードも検証可能
# 例えば、過去にsha256_cryptでハッシュ化されたパスワードがあった場合
legacy_hash = "$5$rounds=80000$wnsT7Yr92oJoP28r$cKhJImk5mfuSKV9b3mumNzlbstFUplKtQXXMo4G6Ep5" # sha256_cryptの例
password_legacy = "password"

is_legacy_correct = pwd_context.verify(password_legacy, legacy_hash)
print(f"検証結果 (sha256_crypt): {is_legacy_correct}") # True

# 間違ったパスワードでの検証
is_wrong = pwd_context.verify("wrongpass", hashed_password)
print(f"検証結果 (間違い): {is_wrong}") # False

hash() メソッドは、CryptContext で設定されたデフォルトのアルゴリズムを使用してハッシュ化します。
verify() メソッドは、提供されたハッシュ文字列のプレフィックス(例: $2b$, $5$, $argon2id$)からアルゴリズムを自動的に識別し、schemes でサポートされているアルゴリズムであれば検証を実行します。

ハッシュの移行 (Hash Migration)

CryptContext の強力な機能の一つが、非推奨アルゴリズムでハッシュ化されたパスワードを、検証時に自動的に新しいデフォルトアルゴリズムで再ハッシュ化(移行)する機能です。

これを利用するには、verify_and_update() メソッドを使用します。このメソッドは、検証が成功したかどうかを示す真偽値と、ハッシュが更新された場合に新しいハッシュ文字列を返します(更新されなかった場合は None)。

# CryptContextオブジェクトは上記で作成済みとする (bcryptがdefault, sha256_cryptがdeprecated)
# legacy_hash は sha256_crypt でハッシュ化されたパスワードとする
legacy_hash = "$5$rounds=80000$wnsT7Yr92oJoP28r$cKhJImk5mfuSKV9b3mumNzlbstFUplKtQXXMo4G6Ep5"
password_legacy = "password"

# 検証と更新を試みる
needs_update, new_hash = pwd_context.verify_and_update(password_legacy, legacy_hash)

if needs_update:
    print("パスワードハッシュが更新されました!")
    print(f"古いハッシュ: {legacy_hash}")
    print(f"新しいハッシュ (bcrypt): {new_hash}")
    # ここでデータベースのハッシュ値を new_hash に更新する処理を記述
    # db.update_user_password_hash(user_id, new_hash)
else:
    if new_hash is None:
        print("パスワードが一致しませんでした。")
    else:
        print("パスワードは一致しましたが、ハッシュは最新のため更新の必要はありません。")
        print(f"現在のハッシュ: {new_hash}") # new_hashには元のハッシュと同じ値が入る

# すでに最新(bcrypt)のハッシュで試した場合
bcrypt_hash = pwd_context.hash("anothersecret")
needs_update_bcrypt, current_hash = pwd_context.verify_and_update("anothersecret", bcrypt_hash)
if not needs_update_bcrypt and current_hash is not None:
    print("\nすでに最新のハッシュです。")
    print(f"ハッシュ: {current_hash}")

ユーザーがログインするたびに verify_and_update() を呼び出すことで、古いハッシュ形式を使っているユーザーのパスワードを、システムを停止することなく段階的に安全な形式に移行させることができます。これは、セキュリティを継続的に改善するための非常に重要なプラクティスです。

passlibは多種多様なハッシュアルゴリズムをサポートしていますが、新しいアプリケーションで使用するアルゴリズムは慎重に選ぶ必要があります。一般的に、現代的で、計算コスト(ストレッチング)を調整でき、ソルトを適切に扱えるアルゴリズムが推奨されます。

OWASP (Open Web Application Security Project) などのセキュリティ専門機関も、特定のアルゴリズムを推奨しています。

推奨されるハッシュアルゴリズム

アルゴリズム passlibでの名前 特徴 推奨される理由 注意点
Argon2 argon2 2015年のPassword Hashing Competition (PHC) 優勝者。メモリハード関数であり、GPUやカスタムハードウェア(ASIC/FPGA)による攻撃への耐性が高い。3つのモード (Argon2d, Argon2i, Argon2id) がある。 現在最も強力で推奨されるアルゴリズムの一つ。特に Argon2id がバランスが取れている。 比較的新しいため、古いシステムやライブラリでのサポートが限定的。argon2-cffi ライブラリが必要。メモリ使用量もパラメータとなる。
bcrypt bcrypt Blowfish暗号に基づいたハッシュ関数。計算コスト(rounds)を調整可能で、長年にわたり広く利用されている実績がある。 実績があり、多くのプラットフォームや言語でサポートされている。CPU負荷を高くすることでブルートフォース攻撃を遅らせる。 メモリハードではないため、Argon2ほどのGPU耐性はない。パスワード長に72バイトの制限がある(passlibでは内部的に対処)。bcrypt ライブラリが必要。
scrypt scrypt bcryptと同様に計算コストを調整可能だが、さらにメモリ使用量もパラメータとして調整できるメモリハード関数。 bcryptよりもGPUやカスタムハードウェア攻撃への耐性が高いとされる。 bcryptやArgon2に比べて採用例が少ない。適切なパラメータ設定がbcryptより複雑。必要なメモリ量が大きい場合がある。scrypt ライブラリが必要。
PBKDF2 pbkdf2_sha256
pbkdf2_sha512
Password-Based Key Derivation Function 2。HMAC (SHA256やSHA512など) を内部で使用し、反復回数(rounds)を調整可能。 NIST(米国国立標準技術研究所)などの標準化団体によって推奨されている。多くのフレームワークやライブラリでサポートされている。FIPS 140-2準拠が必要な場合に適している。 メモリハードではないため、GPU攻撃への耐性はbcryptやscrypt, Argon2に劣る。反復回数を十分に高く設定する必要がある。
SHA-Crypt sha256_crypt
sha512_crypt
MD5-CryptやDES-Cryptの後継として開発された。Linuxの標準的なパスワードハッシュ形式として広く使われている。反復回数(rounds)を調整可能。 広く普及しており、OSレベルでのサポートがある場合が多い。PBKDF2と同様に反復計算により攻撃を遅延させる。 メモリハードではない。PBKDF2やbcryptと比較して、新しい設計思想のアルゴリズムではない。

避けるべき、または非推奨のアルゴリズム

以下のアルゴリズムは、脆弱性が知られているか、現代の計算能力に対して不十分であるため、新しいアプリケーションでの使用は避けるべきです。既存システムとの互換性のためにpasslibでサポートされていますが、可能な限り推奨アルゴリズムへの移行を目指しましょう。

  • MD5: md5_crypt, apr_md5_crypt – 衝突攻撃に対して非常に脆弱。
  • SHA-1: sha1_crypt – MD5と同様に脆弱性が指摘されている。
  • DES: des_crypt – 計算コストが低く、現代のハードウェアでは容易に破られる。
  • 平文・その他弱いハッシュ: plaintext, bsdi_crypt, crypt16 など

アルゴリズム選択の指針

  1. 最優先: Argon2 (特に Argon2id) – 現時点で最も強力な選択肢。
  2. 次点: bcrypt – 実績と互換性を重視する場合の堅実な選択肢。
  3. 標準準拠: PBKDF2 (SHA256/SHA512) – FIPS準拠など、特定の標準が必要な場合。
  4. その他: scrypt, SHA-Crypt – 特定の要件がある場合や、既存システムとの兼ね合いで検討。

選択したら、CryptContext で推奨アルゴリズムを default に設定し、他のサポートするアルゴリズムを schemes に含め、古いものは deprecated に指定するのが良いでしょう。

コストパラメータの調整 ⚖️: 推奨アルゴリズムの多くは、計算コスト(rounds, cost factor, メモリ量など)を調整できます。この値は、ユーザーのログイン時間に影響を与えずに、攻撃者がブルートフォース攻撃を行う時間を最大化するように設定する必要があります。一般的には、許容できる遅延(例: 250ms〜500ms程度)になる最大の値を設定します。passlibのデフォルト値は多くの場合、良い出発点となりますが、ターゲット環境のCPU性能に応じて調整することが推奨されます。

passlibは安全なパスワードハッシュ化を容易にしますが、ライブラリを使うだけで万全というわけではありません。以下の点にも注意が必要です。

  • ソルト (Salt): パスワードをハッシュ化する際には、必ずユーザーごとにユニークなランダムなソルトを使用する必要があります。ソルトは、同じパスワードでもユーザーごとに異なるハッシュ値が生成されるようにし、レインボーテーブル攻撃(事前計算されたハッシュ値リストによる攻撃)を防ぐのに役立ちます。passlibは通常、hash() メソッド内で自動的に適切な長さのランダムソルトを生成し、ハッシュ文字列に含めて保存します。特別な理由がない限り、手動でソルトを管理する必要はありません。
  • ストレッチング (Stretching) / 計算コスト: bcrypt, PBKDF2, Argon2, scryptなどのアルゴリズムは、計算コスト(反復回数やメモリ使用量)を調整できます。このコストを高めることで、攻撃者がパスワードを推測(ブルートフォース)するために必要な時間を指数関数的に増加させることができます。passlibのデフォルト値は一般的に安全とされていますが、サーバーの性能が許す限り、ユーザー体験を損なわない範囲で(例えばログインに0.5秒以内)、コストを高く設定することが推奨されます。
  • ペッパー (Pepper): ペッパーは、すべてのパスワードハッシュに対して追加される、システム全体で共通の秘密の文字列です。データベースが漏洩しても、ペッパーが漏洩しなければ、オフラインでのブルートフォース攻撃をさらに困難にすることができます。ただし、ペッパーの管理(安全な保存場所、ローテーションなど)は複雑であり、適切に管理されないと効果がない、あるいはリスクになる可能性もあります。passlib自体にはペッパーを直接管理する機能はありませんが、アプリケーションレベルで実装することは可能です。一般的には、強力なハッシュアルゴリズムと適切なソルト、ストレッチングがあれば、ペッパーなしでも十分安全とみなされることが多いです。
  • アルゴリズムの選択と移行: 前述の通り、常に推奨される最新のアルゴリズムを使用し、古いアルゴリズムは非推奨として移行を進めるべきです。CryptContextverify_and_update() がこれを支援します。
  • パスワードポリシー: ライブラリだけでなく、ユーザーに複雑なパスワード(長さ、文字種など)を設定させる、パスワードの使い回しを避けるよう促す、定期的な変更(議論あり)を推奨するなど、アプリケーションレベルでのパスワードポリシーも重要です。
  • 総当たり攻撃対策: ログイン試行回数に制限を設け、短時間に何度も失敗したアカウントやIPアドレスを一時的または恒久的にロックアウトするなどの対策も組み合わせるべきです。
  • HTTPSの使用: パスワードがクライアントからサーバーへ送信される際は、必ずHTTPSを使用して通信を暗号化し、盗聴を防ぎます。

絶対にしてはいけないこと 🚫

  • パスワードを平文で保存する。
  • ソルトなしでハッシュ化する。
  • MD5やSHA1など、脆弱なハッシュアルゴリズムを使用する。
  • 計算コスト(ストレッチング回数)を低く設定しすぎる。
  • 独自(自作)の暗号化・ハッシュ化アルゴリズムを使用する(専門家でない限り、安全性を保証するのは極めて困難です)。

passlibは基本的なハッシュ化・検証以外にも、いくつかの高度な機能やユーティリティを提供しています。

特定のパラメータでのハッシュ化

デフォルト設定ではなく、特定のパラメータ(例: rounds)を指定してハッシュ化したい場合は、using() メソッドを使用します。

from passlib.hash import bcrypt

# デフォルトのroundsでハッシュ化
hash_default = bcrypt.hash("password")
print(f"デフォルト: {hash_default}")

# rounds=14 を指定してハッシュ化
hash_custom = bcrypt.using(rounds=14).hash("password")
print(f"Rounds=14: {hash_custom}")

# CryptContextでも同様に可能
# pwd_context.using(scheme="bcrypt", rounds=14).hash("password")

ハッシュ文字列の解析

identify() メソッドや info() オブジェクトを使うと、ハッシュ文字列がどのアルゴリズムのものかを識別したり、詳細情報を取得したりできます。

# CryptContextオブジェクトは上記で作成済みとする
bcrypt_hash = "$2b$12$kFluqntgQAgpH.Q9gfNrb.9R0WHyAxVR2h5hXg2XrBPGXhQAqv7Ty"
sha256_hash = "$5$rounds=80000$wnsT7Yr92oJoP28r$cKhJImk5mfuSKV9b3mumNzlbstFUplKtQXXMo4G6Ep5"
unknown_hash = "thisisnotahash"

# ハッシュの識別
print(f"'{bcrypt_hash[:15]}...' の識別結果: {pwd_context.identify(bcrypt_hash)}") # bcrypt
print(f"'{sha256_hash[:15]}...' の識別結果: {pwd_context.identify(sha256_hash)}") # sha256_crypt
try:
    print(f"'{unknown_hash}' の識別結果: {pwd_context.identify(unknown_hash)}")
except ValueError as e:
    print(f"'{unknown_hash}' の識別結果: エラー ({e})") # エラー

# ハッシュ情報の取得 (CryptContext経由)
info = pwd_context.info(bcrypt_hash)
if info:
    print(f"\nBcryptハッシュ情報:")
    print(f"  Scheme: {info.scheme}")
    print(f"  Context Rounds: {info.context_rounds}") # CryptContextで設定されたrounds (未設定ならNone)
    print(f"  Actual Rounds: {getattr(info.handler, 'rounds', 'N/A')}") # ハッシュ自体に含まれるrounds (bcryptの場合)
else:
    print("\n有効なハッシュではありません。")

設定の読み込みと保存

CryptContext の設定は、辞書やINI形式の文字列/ファイルから読み込んだり、書き出したりすることができます。これにより、パスワードポリシーをコードから分離して管理できます。

from passlib.context import CryptContext

# 設定を辞書で定義
config_dict = {
    "schemes": ["argon2", "bcrypt"],
    "default": "argon2",
    "argon2__rounds": 12,
    "deprecated": "auto",
}

# 辞書からCryptContextを作成
context_from_dict = CryptContext.from_dict(config_dict)
print("辞書から作成:", context_from_dict.to_dict())

# 設定をINI形式の文字列で定義
config_string = """
[passlib]
schemes = argon2, bcrypt
default = argon2
argon2__rounds = 12
deprecated = auto
"""

# 文字列からCryptContextを作成
context_from_string = CryptContext.from_string(config_string)
print("文字列から作成:", context_from_string.to_string())

# ファイルから読み込む場合
# with open("passlib.cfg", "w") as f:
#     f.write(config_string)
# context_from_file = CryptContext.from_path("passlib.cfg")
# print("ファイルから作成:", context_from_file.to_dict())

# 既存のコンテキストに設定をロードすることも可能
# existing_context = CryptContext()
# existing_context.load(config_dict)

TOTP (Time-based One-Time Password) サポート

passlibは、二要素認証(2FA)でよく使われるTOTPの生成と検証もサポートしています (passlib.totp)。

from passlib.totp import TOTP

# アプリケーション全体で共有する秘密鍵 (ランダムに生成し、安全に保存)
# import os; app_secret = os.urandom(24)
app_secret = b'앱_시크릿_키_예제_바이트_문자열' # 実際にはランダム生成する

# TOTPファクトリを作成 (推奨)
totp_factory = TOTP.using(secrets={"1": app_secret}, issuer="MyWebApp", alg="sha256")

# ユーザーごとにTOTPインスタンスを作成・保存
user_secret_key = totp_factory.new_random_secret()
user_totp = totp_factory.new(key=user_secret_key, label="user@example.com")

# 設定用URI (Google Authenticatorなどに登録)
uri = user_totp.to_uri()
print(f"設定用URI: {uri}")

# トークンの生成 (通常クライアント側で行う)
# token = user_totp.now()
# print(f"現在のトークン: {token}")

# トークンの検証 (サーバー側)
# user_input_token = input("Authenticatorアプリのコードを入力してください: ")
user_input_token = "123456" # 仮の入力
match = user_totp.verify(user_input_token)

if match:
    print("トークンは有効です。")
else:
    print("トークンが無効か期限切れです。")

# TOTPオブジェクトのシリアライズ/デシリアライズ (保存・復元用)
# serialized = user_totp.to_json()
# restored_totp = totp_factory.from_json(serialized)

TOTP機能を使うことで、パスワードに加えて時間ベースのワンタイムパスワードによる認証層を追加し、セキュリティを強化できます。

passlibは、Pythonアプリケーションにおけるパスワード管理の複雑さを大幅に軽減し、セキュリティを向上させるための強力なライブラリです。

  • bcrypt, Argon2, PBKDF2など、推奨される強力なハッシュアルゴリズムを簡単に利用できます。
  • CryptContext を使うことで、パスワードポリシー(アルゴリズム選択、パラメータ、非推奨設定)を一元管理できます。
  • verify_and_update() により、古いハッシュ形式から新しい形式への安全な移行を自動化できます。
  • ソルトの自動生成や検証時のアルゴリズム自動識別など、面倒な詳細を隠蔽してくれます。
  • TOTPサポートにより、二要素認証の実装も可能です。

Webアプリケーション開発において、ユーザー認証は基本的ながら非常に重要な要素です。passlibを活用することで、開発者はセキュリティのベストプラクティスに沿った堅牢なパスワード管理システムを、比較的容易に構築することができます。ぜひ、あなたの次のPythonプロジェクトでpasslibの導入を検討してみてください! 💪

より詳細な情報や最新のドキュメントについては、passlib公式ドキュメント を参照してください。

コメント

タイトルとURLをコピーしました