読者です 読者をやめる 読者になる 読者になる

「Protecting Passwords」というタイトルで発表した

開発者・ユーザそれぞれの立場から、パスワードを守る方法について発表した。

最も強いパスワードは完全なランダム、最も適切な管理方法はサービスごとにまったく異なるパスワードを使うことであるのは間違いないが、利便性を考えるとあまり現実的ではないと思う。 パスワードマネージャによる管理も、スマートフォンやネットカフェなどからアクセスするような場合においては逆に不便になることもある。 「強いパスワード」を考えるあまり強く安全性に配慮したアドバイスがされることもあるが、自分としては「弱いパスワードをきちんと避けつつ、ほどほどに強いパスワードを利用する」アプローチで考えたい。

また、開発者の側ではパスワードをハッシュ化して保存すべきという話がよく言われるが、鍵導出関数(Key Deviation Functions)の利用にまで踏み込んだ話をWeb上で見る機会が少ないような気がするので、この話も盛り込んだ。 鍵導出関数の実装は、Python(2.7.8および3.4以降)、RubyPHP(5.5.0以降)のそれぞれにおいて標準で提供されている。 例として、Python3で鍵導出関数PBKDF2によるパスワードハッシュの計算・検証を行うコードを示すと次のようになる。

# password_hash.py
import os
import hashlib

def compute_pwhash(password):
    salt = os.urandom(16)
    digest = hashlib.pbkdf2_hmac('sha256', str.encode(password), salt, 100000)
    return salt + digest

def verify_pwhash(pwhash, password):
    salt, digest = pwhash[:16], pwhash[16:]
    digest_new = hashlib.pbkdf2_hmac('sha256', str.encode(password), salt, 100000)
    return digest_new == digest

if __name__ == '__main__':
    pwhash = compute_pwhash('password')
    print("password hash: %r" % pwhash)

    password = input('type password: ')
    print(verify_pwhash(pwhash, password))
$ python3 --version
Python 3.4.3

$ python3 password_hash.py
password hash: b']\xc8\xfb\xde9F\xc9E\x03\x1bW\x1c\x97\x19\xa1v\xdfe\xaa\x97\xae\xb2\xe7\xaf\xb3\x12\x13\xd7\x82\xbb\x83\x9fW`$\xdaT\xeb\x90\x8c\xa4\x01n\xde2E\xce5'
type password: password
True

$ python3 password_hash.py
password hash: b'N\xeb"(\xf5Bb\r\x03\xd2\x13\n\x9bD2\x1bN\xa6\x07\x05h9\xa6!\x00{A\xf4$\xd9d\x90\x0e\x8d?c|\x06]s{\xc7\xa2\x15\xbb\xc6\x9b\x18'
type password: foobar
False

パスワードに関してはさまざまな考え方があると思うが、ひとつの参考になればよいと思う。 発表の機会をくださった#ssmjpのみなさま、ありがとうございました。