【Pythonセキュリティ入門】なぜ`random`ではなく`secrets`?安全なパスワードを生成するための必須知識

「パスワード生成アプリの記事で、なぜ`random`じゃなくて`secrets`っていう、あまり聞かないモジュールを使ったの?」
「どっちも『ランダム』なんでしょ?何が違うの?」
「自分のプログラムで、セキュリティ上安全な乱数が必要になったらどうすればいい?」

こんにちは! Pythonプログラミング探検隊、隊長のPythonistaです! 先日公開した「Tkinter実践プロジェクト!高機能なパスワード自動生成アプリ」では、パスワードを生成する心臓部で`secrets`というモジュールを使用しました。

多くの方がPythonで乱数といえば`random`モジュールを思い浮かべるでしょう。なぜ、あえて`secrets`モジュールを選んだのか? 実は、この2つのモジュールには**「予測可能性」**という点で、天と地ほどの決定的な違いがあるのです。

今回の補完ブログでは、この違いを深掘りし、**なぜセキュリティが関わる場面では`secrets`モジュールが絶対に必要不可か**を、分かりやすい例え話を交えて徹底解説します。この知識は、あなたが将来、安全なアプリケーションを開発するための重要な基礎となります。


1. `random`モジュール:シミュレーションとゲームの名脇役

まず、おなじみの`random`モジュールについてです。このモジュールは、ゲームのサイコロの目を決めたり、リストからランダムに要素を選んだり、科学技術計算のシミュレーションで使われたりと、非常に多くの場面で活躍します。

しかし、`random`モジュールが生み出す乱数は、専門的には**「疑似乱数(Pseudo-random)」**と呼ばれます。これは「本物っぽく見えるけど、実は偽物(予測可能)」な乱数だという意味です。

例えるなら「巨大なレシピ本」

`random`モジュールの仕組みは、**非常に分厚く、複雑な計算式が書かれた「レシピ本」**のようなものです。

「シード値」と呼ばれる、本の読み始めのページ番号と行番号さえ分かってしまえば、その次にどの数字(乱数)が書かれているかは、計算によって**完全に予測できてしまいます**。シード値が同じなら、何度やっても全く同じ順番で「ランダムな」数列が生成されるのです。これは、科学実験の結果を再現したい場合などには非常に便利な性質です。

しかし、パスワードのような「他人に予測されては絶対に困るもの」を生成するのに、予測可能なレシピ本を使うのがどれほど危険か、お分かりいただけるでしょう。


2. `secrets`モジュール:セキュリティ専門のヒーロー

そこで登場するのが、Python 3.6から標準ライブラリに加わった`secrets`モジュールです。このモジュールは、その名の通り**セキュリティトークンやパスワードなど、秘密の情報を管理するために特別に設計**されています。

`secrets`モジュールが生み出す乱数は、**「暗号学的に安全な疑似乱数(Cryptographically Secure Pseudo-random)」**と呼ばれます。これは、予測が事実上不可能であることを意味します。

例えるなら「混沌としたイベントのスープ」

`secrets`モジュールの乱数の源は、予測可能なレシピ本ではありません。それは、お使いのコンピュータのOS(オペレーティングシステム)が管理する**「エントロピー・プール」**というものです。

このプールは、**予測不可能な物理現象やイベントをごちゃまぜにした「混沌のスープ」**のようなものです。中には、

  • あなたのマウスの動きのマイクロ秒単位のタイミング
  • キーボードの打鍵間隔
  • ネットワークからパケットが到着するタイミング
  • ハードディスクの読み書きヘッドのノイズ

といった、再現性がなく、外部から観測・予測することが極めて困難な情報が常に投入され続けています。`secrets`モジュールは、この混沌のスープから乱数を汲み出してくるため、生成される値は**事実上、予測不可能**なのです。


3. `random` vs `secrets` 比較まとめ

両者の違いをまとめると、以下のようになります。


    `random`モジュールが生み出す乱数=「疑似乱数(Pseudo-random)」

    これは「本物っぽく見えるけど、実は偽物(予測可能)」な乱数


        `secrets`モジュールが生み出す乱数=「暗号学的に安全な疑似乱数(Cryptographically Secure Pseudo-random)」

    これは、予測が事実上不可能


使い方はrandom.choice()secrets.choice()のように非常によく似ていますが、その背景にある信頼性は全くの別物なのです。


4. 結論:適切な道具を、適切な場所で

今回の探検で、`random`と`secrets`の決定的な違いがお分かりいただけたと思います。結論は非常にシンプルです。

日常的な「ちょっとしたランダム」が欲しいときは手軽な random を。
セキュリティが少しでも関わる、絶対に推測されてはならない値を扱うときは、必ず secrets を使う。

私たちのパスワード生成アプリが、なぜsecrets.choice()を使って文字を選んでいたのか、その理由がここにあります。それは、ユーザーに信頼性の高い、安全なパスワードを提供するための、開発者としての重要な選択だったのです。

あなたの今後のプログラミングライフにおいても、この「適切な道具を、適切な場所で選ぶ」という視点をぜひ大切にしてください。

さて、セキュリティの「なぜ?」が解決したところで、次の補完ブログでは、あのアプリを使いやすくしている**TkinterのUI設計テクニック**について深掘りしていきます。お楽しみに!

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

【Pythonで学ぶ地理計算】mathライブラリで2点間の方位角を計算する基礎 🌍

これで迷わない!WindowsでPython環境構築する一番やさしい方法 #0