メッセージダイジェスト(MD)、メッセージ認証コード(MAC)、鍵導出関数(KDF)の違いについてのメモ

「ハッシュ」という言葉があいまいに使われている場面をしばしば目にするので、関係する概念とそれらの違いについてまとめてみる。

メッセージダイジェスト(Message Digest; MD)

MD5SHA-1、SHA-256など、あるバイト列(メッセージ)に対し固定長の要約値を求めるアルゴリズム。 メッセージの同一性判定に用いられる。

同一の要約値となる(異なる)メッセージの組を求めることが計算量的に困難(強衝突耐性)なものをメッセージダイジェストと呼び、暗号学的ハッシュ関数とも呼ばれる。 同一の要約値となるメッセージの組が容易に求められるものは、誤り検出符号と呼ばれ区別される。 CRC32は誤り検出符号の一種である。

PythonでSHA-256を用いてメッセージダイジェストを求める例を次に示す。

$ python
Python 2.7.5 (default, Oct  2 2013, 22:34:09)
[GCC 4.8.1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> hashlib.sha256('foobar').hexdigest()
'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2'

メッセージ認証コード(Message Authentication Code; MAC

あるバイト列(メッセージ)に対し共通鍵を用いて固定長のバイト列を求めるアルゴリズム。 メッセージの改ざん検知に用いられる。

共通鍵を用いる点においてメッセージダイジェストと異なり、完全性を保護しメッセージの改ざんを防ぐことができる。 つまり、メッセージダイジェストではメッセージ改ざん後の値を容易に計算できるのに対し、メッセージ認証コードでは共通鍵がなければ計算できない。 また、デジタル署名とは公開鍵ではなく共通鍵を用いている点において異なり、否認防止の性質をもたない。 つまり、デジタル署名では公開鍵の持ち主がメッセージを生成したことが保証されるのに対し、メッセージ認証コードでは誰がメッセージを生成したかを特定することはできない。

メッセージ認証コードには、ハッシュ関数を用いる方式(HMAC)とブロック暗号アルゴリズムを用いる方式(CBC-MACなど)がある。 PythonでSHA-256を用いたHMACを求める例を次に示す。

$ python
Python 2.7.10 (default, Jun  1 2015, 18:05:38)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import hashlib
>>> import hmac
>>> key = os.urandom(16)
>>> hmac.new(key, 'foobar', hashlib.sha256).hexdigest()
'05d531abfb693adcb3adbdc0cd3800404636fd1726ad851c86e61683cf33c7f0'

鍵導出関数(Key Derivation Function; KDF)

秘密のバイト列(マスター鍵)から固定長の新たな鍵となるバイト列を求める(導出する)アルゴリズム。 ブロック暗号アルゴリズムに用いるのに適した、固定長で一定のエントロピーを持つより安全な鍵を得ることができる。 また、パラメータに繰り返し回数などを取ることで計算量を調整できるようになっており、導出された鍵からマスター鍵を総当たりで求めることが難しくなっている。 このため、データベースに保存しておくためのパスワードの安全な変換に適している。

Python(2.7.8、3.4以降)でHMAC SHA-256を用いたPBKDF2により新たな鍵を求める例を次に示す。

$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import hashlib
>>> import binascii
>>> salt = os.urandom(16)
>>> derived_key = hashlib.pbkdf2_hmac('sha256', b'foobar', salt, 100000)
>>> binascii.hexlify(derived_key)
b'e3fddc16c83da4ef7f6942f90111b2f129ec8b528a8ae8373ad89592285fab6c'

紙の手帳を使い始めた

ここ数年スケジュール管理にスマートフォンのスケジューラを使っていたが、紙の手帳を買ってあらためてこれを使い始めた。 メリットとデメリットのメモ。

紙の手帳のメリット

  • スケジュール、タスクリスト、メモを集約できる
  • ペンケースを兼ねる
  • 書き込みの自由度が高く、開始時刻あるいは終了時刻の省略ができる
  • 一度書いた情報が時系列で残るため、探す手間が減る
  • 時間の使い方に意識が向くようになり、モチベーション維持に役立つ

紙の手帳のデメリット

  • スマートフォンと比べて大きく、取り出すのに一手間かかる
  • 周期的なスケジュールの記録が困難
  • アラームがないため、頻繁に見返す必要がある
  • カレンダー同期ができないため、適宜転記する必要がある

留意事項

  • When、Where、Whatが重要、Who、Why、Howは必要に応じて補足
  • 確定していない終了時刻等は記録しないほうがよい

所感

デジタルに対するアナログの最も顕著な違いは「あらかじめスペースの確保がされる」ことにあるように思う。 これにより、アナログは「埋める」「書き加える」、デジタルは「置く」「更新する」といった感覚の違いがあらわれる。 デジタルにおける管理ではタスクトラッカーのタスクやWikiのページがやたら増えていき、整理がおろそかになることが起こりがちであるが、細かい粒度であえてスペースに制約を加えることでデジタル特有の問題を解消できる可能性がある。

「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のみなさま、ありがとうございました。

VR TheaterでGear VRを体験してみた

VRを体験してみたくなったので、ネットカフェでヘッドマウントディスプレイGear VRを体験できるVR Theaterに行ってみた。 自分が行った店舗では、有料動画を見る見ないに関わらず、ネットカフェの利用料金とは別に600円が必要だった。

いくつかあるコンテンツのうち、以下の4本を見た。

攻殻機動隊 新劇場版 Virtual Reality Diver

15分の3Dアニメ。自分の意思とは関係なくカメラ(視点)が動くので、酔いそうになる。 目線を動かしたりしていると、けっこう疲弊する。連続して見続けられるのは15分が限界のように感じた。

VR桃神祭2015

3分のライブダイジェスト映像。固定カメラなので酔いは少ないが、主にステージからの視点なので実際に客席から見るのとは違った感じ。 ステージからの視点を体験できるという点ではある意味おもしろい。

初音ミク VR Special LIVE

3分のミュージックビデオ。好きな人は好きそうな感じ。途中初音ミクが目前に接近してくる場面があるのだが、「体を引きたくても引けない」ため拘束されている感覚を体験できる。 斧とかナメクジが飛んでくる感じだと拷問になりそう。

恐竜戯画

3分の3D映像。普通。

所感

  • けっこう疲弊するので、15分以上見続けるにはつらい
  • 「体を引きたくても引けない」ところにヘッドマウント型VRの特色/限界がある
  • バイオハザードスタイルで前後移動できる物理レバーがあるとよさそう

最近買ったもの2016

引っ越しに伴いいろいろ買ったので、それらのメモ。

本棚

これまでの経験から本棚はちゃんとしたものを買う必要があることがわかったので、大きいものを買った。

キューブボックス

扉付きのものを買った。 いわゆる「隠す収納」にでき、かつテレビ台にもできる。便利。

オフィスチェア

これまでの経験から中途半端なものだと座らなくなることがわかったので、ハイバックのオフィスチェアを買った。

ブランドものではないが、十分使えて安い。 フローリングに傷がつかないようにラグマットを敷いて使っている。 机は安い折り畳みのものにした。

物干しスタンド

これまでの経験から物干し竿ではバスタオルを干すのがめんどくさいことがわかったので、場所を取らないものを買った。

書籍

技術書以外の本をいろいろ買った。

化学反応をベースに、料理をエンジニアリングの対象として考察した本。 「ギーク的には調理は、ある系に熱を加えることだと捉えることができる」(p.348)といったように、何をどうすれば料理ができるのかについて化学的に説明されている。

マネジメントに関するさまざまなトピックについて、組織行動学の研究成果を交えながら解説した本。 理想論としての側面は否定できないが、説得力がある。

ソフトウェア開発者の「キャリア、マーケティング、学習、生産性、お金、健康、精神」に関するさまざまなトピックについて、著者の考えをまとめた本。 内容が幅広く、興味深く読める。

オムニバスCD

部屋を集中できる環境にするために、ちょうどいい感じのBGMにできるCDを借りた(買ってない)。

「with Summer Breeze」じゃないほう。昼っぽい。

同じタイトルのCDがいくつかあるので注意。夜っぽい。

いわゆる定番の曲がだいたい入っている2枚組。

とくに何もしていないときに流すのにちょうどいい感じ。

ワンルームインテリアのメモ

以下の二つを考慮すれば、だいたいいい感じになる。

  • ベッドは入口から向かって横に置くことで、スペースを広く使うことができる。間に仕切りになるものを置くと空間を区切ることができ、なおよい。
  • 家具の色調を揃える。

関連リンク

Twitterのツイート時刻を可視化する「TwiActivity」を作った

D3.jsにちょうどよいサンプルがあったので、任意アカウントのツイート時刻に適用するサイトを作ってみた。 TwitterAPIが1リクエストあたり200件のツイートしか取れないので、とりあえず200件のみで可視化するようにしてある。

特に作るに至った理由はないが、投稿時刻の公開が本当に必要かどうかをサービスを開発する際に一考するきっかけになれば、と思う。

Fire TV Stickを買った

「Raspberry PiにKodiをインストールしてネットテレビを作る」でネットテレビを作ってみたが、Raspberry Pi上のKodiではNetflixを見るのが難しかった。 そこで、ちょうどセールで20%オフになったFire TV Stickを買った。 Amazonプライムビデオに加え、アプリを入れることでYouTubeNetflix、Hulu、dTV、ニコニコ動画の再生が可能。 実体はARMのAndroidなので、アプリとしてES File Explorerをインストールし、Kodiのapkファイルを転送すればKodiを動かすこともできる(参考)。

リモコンがついてきて便利。

f:id:inaz2:20160601234838p:plain