python3でbcryptを使ってパスワード認証をつくる
タイトルの通りです.試したら上手くいったやーつなのであまり当てにしないこと.参考文献は一番下にまとめて載っけています.
bcryptを使って.htpasswdファイルを生成してBASIC認証実装している日本人はビックリするほど存在していないようで.役に立つ人もいるかも,と思い投稿します.ひょっとしたらBASIC認証自体が弱いからわざわざこういうことしないってことなのかな.偉い人教えてください.
.htpasswdの生成
以下のコマンドでファイルを生成します.
htpasswd -Bcb .htpasswd user passwd
詳細について全部は説明しませんが,大文字のBがbcryptを使った暗号化を指定するオプションです.
\(๑╹◡╹)ノ>>>htpasswd
Usage:
htpasswd [-cimBdpsDv] [-C cost] passwordfile username
htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password
htpasswd -n[imBdps] [-C cost] username
htpasswd -nb[mBdps] [-C cost] username password
-c Create a new file.
-n Don't update file; display results on stdout.
-b Use the password from the command line rather than prompting for it.
-i Read password from stdin without verification (for script usage).
-m Force MD5 encryption of the password (default).
-B Force bcrypt encryption of the password (very secure).
-C Set the computing time used for the bcrypt algorithm
(higher is more secure but slower, default: 5, valid: 4 to 31).
-d Force CRYPT encryption of the password (8 chars max, insecure).
-s Force SHA encryption of the password (insecure).
-p Do not encrypt the password (plaintext, insecure).
-D Delete the specified user.
-v Verify password for the specified user.
On other systems than Windows and NetWare the '-p' flag will probably not work.
The SHA algorithm does not use a salt and is less secure than the MD5 algorithm.
上記のマニュアルを見れば分かる通り,他の暗号化オプションはだいたいinsecureと記載されているので,みんなbcryptを使おうなというお話のようです.調べた限りでは,実際他よりも安全らしい.
Python上での実装
生で実装とか無謀なので,ライブラリ使います.
pip install bcrypt
あとはライブラリに実装されている関数を使う.が,その前に.htpasswdそのものの中身を開かないといけない.
import bcrypt def basic_check(user, password): passwd_file = open(root_path + "/../config/.htpasswd", mode="r") hashed_line = passwd_file.readline() passwd_file.close() hashed_user, hashed_passwd = hashed_line.strip().split(":")
strip()でファイルに含まれる改行を取り除いて,split()でユーザ名とパスワードをわけて代入するところがミソ.↑の関数内に以下のような一文を加えて判定する.
return bcrypt.hashpw(password.encode("utf-8"), hashed_passwd.encode("utf-8")) == hashed_passwd.encode("utf-8") \ and user == hashed_user
bytesにしないといけないので忘れてはいけない.あとはこれをWebアプリなりなんなりに実装する.
以下参考文献.
pythonでbottleで暗号化パスワード(.htpasswd)でのBasic認証 - Qiita
Salt and pepper - How to encrypt database passwords
CRYPT_BLOWFISHのアルゴリズム$2a$, $2x$, $2y$について英語のドキュメントを読んでみた | kanonjiのブログ
python - Why can bcrypt.hashpw be used both for hashing and verifying passwords? - Stack Overflow
python - How to store and compare password in db using py-bcrypt - Stack Overflow