blog.monophile.net

コンピュータに関するメモ。

著者

山本一彰(Takaaki Yamamoto)

東京工業大学において計算機科学と応用数学を学び、 情報科学芸術大学院大学[IAMAS]においてメディア表現を専攻し修了。 2015年にコンビネータ論理を基に計算完備な計算手法 "論理珠算"を開発し、 それを含む体系である"算道"を構成した。 その成果により、2016年に 第19回 文化庁メディア芸術祭 アート部門 新人賞 (文部科学大臣賞) を受賞。 現在はSRE(サイト信頼性エンジニア)として生計をたててている。

投稿

Python の passlib でハッシュ値を指定のソルトで計算する

概要

/etc/shadow に書かれるハッシュ値を自動生成したくなったので、調べてみた。 Ansible と組み合わせたいので、Python の passlib を使う。

他ブログでも方法は紹介されているが、 passlib で非推奨になっているメソッドが使われていたので、 公式ドキュメントみながら確かめてみた。

例えば、2.0になった段階で encrypt() は廃止されて、hash() のみになるようす。 現時点では passlib は 1.7 だが、1.7 では両方とも使用可能。

なお、ハッシュ値の形式は次の様になっているらしい。

${{ algorithm }}${{ option }}${{ salt }}${{ hash }}

各種OSの /etc/shadow で使えるハッシュアルゴリズムの一覧

各種OSで使えるアルゴリズムは下記から得られる。

↑の出力は↓。

Linux: sha512_crypt, sha256_crypt, md5_crypt, des_crypt, unix_disabled
FreeBSD: bcrypt, md5_crypt, bsd_nthash, des_crypt, unix_disabled
OpenBSD: bcrypt, md5_crypt, bsdi_crypt, des_crypt, unix_disabled

FreeBSD は 9.1 から sha512 に対応しているらしい。 細かく設定したい場合は自分で CryptContext を作る。

ソルトの長さを確認しておく

アルゴリズムによって使えるソルトの長さが異なるので、上記で確認しておく。

  • sha512: [./0-9A-Za-z] 0-16文字
  • sha256: [./0-9A-Za-z] 0-16文字
  • bcrypt: [./0-9A-Za-z] 22文字

平文パスワードからハッシュを計算する (ソルトの指定なし)

ソルトの指定をしないでハッシュを計算する。 この場合は自動でソルトが生成されていることがわかる。

↑の出力は↓。

sha512('secretsecret') -> '$6$rounds=656000$fcD6caqZ.HTe7aO0$0v1Xsq6tFVQVGnNX4M9A9g/UrvhJYeK53JmFl0xXmqAH5n2Mqt8XbqzX9E5VZrxXltek4CsM1ERgpIfxJRQ/l0'
verify: True

平文パスワードからハッシュを計算する (ソルトの指定あり)

ソルトを指定してハッシュを計算する。

↑の出力は↓。

sha512('secretsecret') -> '$6$rounds=656000$saltsalt$Toz2h6NEmqzQZDpBJHIq3Bp1mExBVFK7rSGitHQ9F90ji1pHLC/yEAi5fbGkPpIhpMoBkY9icINEdTceZe6Ur.'
verify: True

(おまけ)ハッシュ値からアルゴリズムを特定し、内容をパースする

対象とするアルゴリズムを指定して、そのハッシュ内容をパースする場合は↓のようにすればよい。

↑の出力は↓。

checksum: Toz2h6NEmqzQZDpBJHIq3Bp1mExBVFK7rSGitHQ9F90ji1pHLC/yEAi5fbGkPpIhpMoBkY9icINEdTceZe6Ur.
salt: saltsalt
rounds: 656000

備考

上記を見ると rounds=656000 となっているためラウンド数は656000回だが、 glibc の実装のデフォルトは5000回らしい。

(おまけ)mkpasswd でハッシュ値を計算する

Ubuntu や Debian では whois のパッケージに mkpasswd コマンドが含まれている。

↑でインストールすれば、↓のように mkpasswd が使える。

したがって、sha-512で指定のソルト(saltsalt)とパスワード(secretsecret)をrounds=8500のハッシュ値は↓で求められる。

参考