とあるIT企業のインフラエンジニア。プライベートでは開発もちょっとやります。
※本ブログの内容はすべて個人の見解であり、所属する企業とは関連ありません。
2023/09/30 暫く更新停止中m
生活・子育て(10)
FaaS(1)
働き方(2)
SaaS(2)
自作PC(6)
IT入門(1)
IaaS(13)
IDaaS(2)
ITIL(1)
PHP(2)
OS(6)
システム監視(1)
コミュニティ(1)
PCアプリ(10)
ストレージ(4)
ブログ(9)
ActiveDirectory(2)
デバイス(7)
旅行(10)
デザイン(3)
カンファレンス(5)
セキュリティ(9)
インフラ(19)
コーディング(11)
ゲーム(28)
インターネット(18)
未分類(8)
396 [今日]
437 [昨日]
【VLHF】自作ハッシュ関数を作るという愚行と思い出
2021/12/26
セキュリティ
お疲れ様です。
しらせです。
皆さんは普段ハッシュ関数は利用されていますでしょうか?
利用するという表現は一般的には馴染みが無いかもしれません。
実際は、システムに組み込むとか、コマンドを実行するという意味合いが強いかもしれません。
今日はちょっと昔(だいぶ昔)に独自のハッシュ関数を作った件について振り返ろうと思います。
もちろん私は数理系の専門家ではないですし、専ら自作のハッシュ関数を作って使うことは安全性の観点からもNGとされています。
恥ずかしいばかりですが、学生時代の何も知らない自分がやった愚行を本ブログをご覧の皆さんにも共有できればと思います。
過去にFC2ブログで書いていた内容です。
もくじ
ハッシュ関数への興味
ハッシュ関数というものの存在を知ったのは、専門学生時代で基本情報技術者試験に向けてITの基礎を学んでいたときでした。
ファイルや文字列を入力値として、1ビットでも異なると全く違う文字列として出力される点に興味がありました。
しかもどんなに大きいファイルでも数百ビットの固定長に圧縮されて、容易に重複することもなくハッシュ値から元のファイルを推測することも困難です。
例えばSHA1ハッシュの場合、
「abc」という文字列では、
「a9993e364706816aba3e25717850c26c9cd0d89d」
が出力されます。
1文字変えて「abd」という文字では、
「cb4cc28df0fdbe0ecf9d9662e294b118092a5735」
が出力されます。
入力はたった3文字ですが20バイト(160bit)の文字列として出力され、しかも1文字変わると全く違う結果が返ってきます。
「a9993e364706816aba3e25717850c26c9cd0d89d」を見て、「あっ、abcね。」と分かることもありません。
ハッシュ関数はデータの改ざん/破損の検知や、パスワードをsaltと繋げて照合用とするなど、用途は多種多様です。
最近では仮想通貨の仕組みの一部としても使われていますね。
そんなハッシュ関数の持つ特性に惹かれたというのがきっかけです。
自作とアプリへの組み込み
学生時代は時間を持て余しており、便利なWindowsデスクトップアプリを作りたい一心でVisualStudioで無駄にアプリを量産していました。
iPhone3Gが発売して間もないころです。
そんな中で誕生したのがパスワード管理ツール「Information Administrator」です。
初めてプログラミングを通して世に送り出したWindowsアプリです。
1人が持つアカウントやパスワードが今後増えていくだろうと予想して作りました。
当時は情報セキュリティについても知見が少なく、いろんな手法でデータを守ろうと考えを巡らせていました。
- ADドメインとの連携
- 端末情報に紐づけた連携
- 自作ハッシュ関数
- 多重の暗号化
この中で、上2つは実装後まもなく機能として消し去りました。
あまり意味が無かったので。
4つ目の多重の暗号化についても意味はありませんが、アプリの特徴としてIAv2,AKYと今でも引き継がれて使われています。
そして問題が3番目の自作ハッシュ関数です。
暗号化を行う際にデータの改ざん/破損の検知のために複数回ハッシュ値を計算します。
最終的にファイルデータに落とし込む時のハッシュ値の長さを切り詰めたい時がありました。
ただ、計算後のハッシュ値を変に弄ることは推奨されず、短く切ったりすることもアウトであるとうっすら聞いたことはありました。
ハッシュ関数にはいくつかの安全性の観点での重要なポイントがあります。
これらがそれぞれ強固であることが求められるためです。
- 原像計算困難性
- 第2原像計算困難性
- 衝突困難性
でも、どうしても可変長な値が取れるハッシュ関数が欲しい、、
「自分しか知らないアルゴリズムだったら大丈夫じゃね?」
という安易な考えが当時ありました。
アプリへの組み込み
「とにかく1ビットでも異なる情報から、まったく別の情報が生み出せれば良いわけか」
「決まったハッシュ長ではなく、自分で異なる長さのハッシュ値が出せるようにしよう」
恐ろしいことに、当時の私はこのくらいしか考えていませんでした。
そしてできたのがこちらです。
アプリへも組み込めるようにソースコードも公開していました。
(参考)Variable Length Hash Function (可変長ハッシュ関数)
※2011年当時の情報を引っ張りだしてきました。
オープンソースとは謳っているもののライセンスも条件も何も書いてないあたり、当時どれほど無知であったかが分かります。
手動で実行できるアプリも用意していました。
最小は8バイト(64bit)から、最大は8,192バイト(65,536bit)まで対応しています。
見た目はちゃんと動きますし高速に動作します。
8KBものハッシュ値なんか出してどうするつもりなんでしょうね?(笑)
なんら安全性の検証も保証もないただの野良ハッシュ関数です。
提案
ここまででも十分アホなことは分かりました。
この後さらに、なにを思ったかアメリカのNISTに対してこの可変長ハッシュ関数を提案しています。
どのように選定されるかも調べず、どのようなフェーズを踏むかもわからず、まったくの無知の状態の私にNISTのチャンさんがメールを返してくれたのは良い思い出です。
「NISTのSHA3のコンペはもう終わって第3ラウンドやってるんだ。君の出る幕はない。帰ってくれな^^」
そりゃそうですわ。
素人が適当に考えた案を受け入れるわけないやん?
いまさらですが本当にすみません。
危険性の認識
最終的に、この自作ハッシュ関数は静かなうちに消えることになりました。
アプリに組み込んでいた箇所はメンテナンス自体もできない状態になってしまったことで、SHA512に切り替える形で消し去りました。
これを正式にやめるきっかけとなったのがIPAの「情報セキュリティスペシャリスト試験(現、情報処理安全確保支援士試験)」でした。
この試験を勉強していてふと目についた以下のような一文が刺さりました。
「自分で作ったハッシュ関数や暗号化は、安全性の観点で保証がありません。使わないようにしましょう。」
さすがにセキュスペを勉強している本人がクソみたいなハッシュ関数を公開して使っていたらオワリです。
これを使って問題があっても説明できない。
全く知らない人が使って問題になっても嫌だ。
安全性、計算量、計算速度などいろんな観点で検証され、選ばれたものだからこそ安心して使える訳です。
そんなことがあって以後は開発基盤で利用が可能な暗号方式・ハッシュ関数を使うことにしました。
皆さんも学習用に自分で使う分には良いかもしれませんが、「独自」の実装を世に出す際にはご注意ください。
年末にふと昔を思い出したので書いてみました。
以上
おつかれさまでした。