• Skip to main content
  • Skip to primary sidebar
  • ホーム
  • お問い合わせ

ハイパー仕事し隊

思い立った吉日!イロイロ試してオンリーワンの起業家を目指してます!

現在の場所:ホーム / ウェブアプリ関連 / データベースにパスワードを「安全に」登録する方法

データベースにパスワードを「安全に」登録する方法

2018年10月9日

password

私「自分のパスワード忘れたので教えて下さい!」

管理者「こちらではパスワードわかりません。」

私「管理者なんだからわかるだろーーーが!!嫌がらせすんなや!」

っとずっと思ってました。。

迷惑かけた方々、すみません。。笑

アプリ開発をするまで知らなかったのですが、

パスワードはそのままデータベースに保存してはいけない

は当たり前のようですね。

では、どうすれば良いのでしょうか?

ウェブの歴史がながいので、既にイロイロとやり方があるみたいですね。。

本記事ではその内容を紹介していきたいと思います。

結論

ひとことで、アプリ開発者は、

  • 自分で実装せず、ライブラリを使おう!

間違いないですね。笑

長年の知恵と経験が詰まってますので、コミュニティに感謝しながら使いましょ。

STEP 1: パスワードの暗号化

「パスワードはそのままデータベースに保存してはいけない」とはいっても、認証するには入力したパスワードに紐付いた情報は必要ですよね。

そこで一般的には、パスワードをハッシュ関数を用いて暗号化して、その結果を保存します。

なぜハッシュ関数を使うのか?疑問に思いますが、それはハッシュ関数で得られた文字列に以下の特徴があるからです。

  • ハッシュ化で得られた文字列から、元の文字列に戻すことはできない (→ 一方通行の計算式が使われてる)
  • ただ、文字列を何度このハッシュ関数に通しても、同じ結果が得られる

そんなハッシュ関数ですが、実は何種類もあります。。orz

詳しい説明は 、Wikipedia の 「Secure Hash Algorithm」を参照してください。

そのなかでも、SHA-256 が一般的に利用されているようです。

ブロックチェーン技術でも使われていることから、その安全性は理解できますね。

ちなみに、こちらが Python でコーディングしサンプルです。

import hashlib

password = bytes('my-password', 'utf-8')
# または password = b'my-password'

print(hashlib.sha256(password).hexdigest())

 

そしてこちらが “my-password” を SHA-256 を実行した値になります。

6fa2288c361becce3e30ba4c41be7d8ba01e3580566f7acc76a7f99994474c46

一方通行とはいっても、よく使われるパスワードのリスト (ここからよく使われるパスワードを確認できます – Github) をハッシュ化しておけば、簡単にもとのパスワードを探し当てることができます。

また、レインボーテーブルといって、少ないリソースで元の値を見つける手法まであったりもします。(えっ!!笑)

もちろん、それを防ぐ方法はちゃんとあります。

STEP 2: salt による強化

パスワードをハッシュ化しただけではあまりよろしくないことはわかりました。

そこで利用されるのが、salt になります。

料理の味を塩で調整するように、ハッシュ化するパスワードを salt で調整します。

salt とは、ある文字列をパスワードに追加してハッシュすることをいいます。

ユーザーごとに違う salt を設定するのが一般的のようです。

これが Python での実装例。

import hashlib
import base64, os

salt = base64.b64encode(os.urandom(32))

def get_hash_with_salt(password, salt):
    salting_hash256 = hashlib.sha256(salt + password).hexdigest()
    return salting_hash256

print(get_hash_with_salt(password, salt))

 

STEP 3: ストレッチングによる計算負荷の増やす

さらに、ハッシュ値をハッシュ化し、新たなハッシュ値をすることもします!

しかも 1000 回とか 10000 回とか!笑

これはストレッチングと言って、少しでも時間をかけさせることが目的です。

import hashlib
import base64, os

salt = base64.b64encode(os.urandom(32))

def get_hash_with_salt_and_stretching(password, salt):
    salting_hash256 = hashlib.sha256(salt + password).hexdigest()
    for _ in range(1000):
        salting_hash256 = hashlib.sha256(bytes(salting_hash256, 'utf-8')).hexdigest()
    return salting_hash256

print(get_hash_with_salt_and_stretching(password, salt))

 

ってか、ライブラリ使おうぜ

イロイロやってきましたが、やはりライブラリで標準的に準備されていますので、自力でコーディングする必要は全くありません。。笑

import hashlib
import base64, os

salt = base64.b64encode(os.urandom(32))

library_hashed = hashlib.pbkdf2_hmac(
    'sha256', password, salt, 1000
)
print(library_hashed.hex())

 

他にも bcrypt というモジュールもあります。

import bcrypt

# ハッシュ化
hashed_pwd = bcrypt.hashpw(b'my-password', salt)

# チェック
bcrypt.hashpw(b'my-password', hashed_pwd)

salt 値が hashed_pwd から分かるので、salt 値を渡さなく良いみたいです。

それは、安全なのか??と疑問に思いますが、他言語でも比較的よく使われているので、問題ないみたいですね。

100% 安全なパスワードはない

感の良い方はお気づきかと思いますが、salt を付与してもストレッチングをしても、いずれパスワードは探し当てられます。

ただ問題は、どれだけ解読に時間がかかるか? だけです。

一瞬の可能性もありますし、数百年の可能性もあります。

パスワードのクラックは「よく使われるパスワード」→「辞書にある単語」などから実行されるので、ランダムな英数字 + 記号を使った長いパスワードを使ってすぐには解読されないようにする必要がありますね。

なんて、奥が深い。。

カテゴリー: ウェブアプリ関連
タグ: python

最初のサイドバー

簡単な自己紹介

ごく普通の 30 代サラリーマンです。世界を旅しながらの生活が目標!!
IT 全般に興味あり: Python (Flask, Django) / PHP (Laravel, Wordpress) / Golang / AWS / Network Security.
Read More…

サイト内検索

最近の投稿

  • 【VS Code プラグイン】Postman より便利!? Rest Client をオススメする理由
  • MySQL と phpMyAdmin を Docker Compose で作って、Python から接続する
  • Windows10 上の Ubuntu から “curl localhost” を実行すると “Connection refused” になる原因
  • リダイレクトの仕組み知ってる?Flask で調べるてみるのだ。
  • Apple 独自の 検索エンジンで何が変わるのか

アーカイブ

  • 2021年3月
  • 2021年1月
  • 2020年10月
  • 2019年3月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年5月
  • 2018年4月

タグ

amazon cloudfront amazon s3 aws coursera css django docker flask fullstack gcp github hawaii life in USA linux mongodb mysql postgresql pwa python sqlite vagrant

Contact
Privacy Policy and Term of Use
Copyright © 2025 · All rights reserved.