パスワードをソルトなしMD5でハッシュ化する話

2023/8/19作成

ソルト付きハッシュのソルトはどこに保存するのが一般的か

ソルトなしでハッシュ化していたパスワードデータが漏洩してちょっとしたお祭りになっています。セキュリティの専門家からは「いまどきソルト無しMD5なんてありえない」と指摘されています。確かに、2023年になって新規にサービスを実装する際にソルトなしMD5を採用したら、ちょっとあり得ないと思います。でも、そうとも言い切れないケースもあるんじゃないかなというのがこの記事で書きたいことです。

要するにですね、長年運用されてるサービスってどうでしょうって話ですよ。たとえば10年前から運用されているサービスなら、新規に開発されたのは2013年です。2013年時点でもソルトなしMD5はやばそうな気がするな。では20年前から運用されてるサービスと仮定しましょうか。実装されたのは2003年。あんまりはっきりしたことは言えませんが、この頃だとパスワードはハッシュ化せずに保存してても当たり前だったような気もします。ソルトなしMD5でもハッシュ化してれば十分に先進的だったでしょうね。

2003年から運用されているサービスと言うことは、当然にユーザも2003年から存在します。20年に渡って利用し続けているユーザってことですね。このユーザのパスワードはソルトなしMD5でハッシュ化されています。さて、ソルトなしMD5は危険だからやめようとなった場合、この20年前からいるユーザのパスワードはどう扱えばよいでしょう。別のハッシュアルゴリズムを使ってハッシュ化しようにも、オリジナルのパスワードはわかりません。だってソルトなしMD5でハッシュ化されてしまっていますから。

ソルトなしMD5なら元パスワードが容易に復元出来るかというと、そんなことはありません。あくまでも同じハッシュ値を得られる文字列が復元できるというだけであって、それがオリジナルのパスワードではない可能性があります。と思う。この辺誰も指摘してないから、本当にそうだと言い切っていいのはイマイチ自信はありませんが、でも多分正しいと思います。だってハッシュアルゴリズムにはコリジョンがありますからねぇ。

話を戻して20年運営されてるサービスの話です。初期からいるユーザのオリジナルパスワードはサービス側にはわかりませんから、別のハッシュアルゴリズムに変更することは出来ないわけです。「今時ソルトなしMD5を使ってるなんて」って批判されてますが、2023年に新規に開発した場合だけではなく、20年前に開発されて当時からのユーザデータを抱え続けていたってケースもあるわけですよねという話です。

さて、そういう20年運用サービスが実際にあった場合、どういう対策がとれるでしょうか。ぱっと思いつく方法は二つです。一つは、複数のハッシュアルゴリズムを選択できるように修正し、新規ユーザは新しいハッシュアルゴリズムを使うようにします。旧来のユーザもパスワードを変更する際には新アルゴリズムを使いましょう。つまり、生パスワードがわかるタイミングで切り替えていくわけですね。これでしばらくすれば大半のユーザは新アルゴリズムに置き換えられます。旧アルゴリズムのままのユーザにはどこかのタイミングで強制的にパスワードリセットを行って新アルゴリズムに移行すれば完了となります。

もう一つの方法は、ソルトなしMD5のハッシュ値そのものを新しいアルゴリズムでハッシュ化する方法です。要するに一種のストレッチングですね。当然パスワード照合時にも新ハッシュアルゴリズムとソルトなしMD5の両方を施す必要があります。こちらは先ほどのように移行に時間をかける必要は無く、すぐに完了させることが出来ます。でもハッシュがある意味独自のものになってしまいますので、今後の運用の難易度はあがりそうですけどね。

ということで、新アルゴリズムに移行する方法はないでもないですが、ではこれらが実際に採用されるかというと難しい。実務やってる人なら誰も共感してもらえると思いますが、これらの改良ってビジネス的には全くメリットがないんですよね。なので、実装すべき理由をマネージャーやディレクターに説明して必要性は理解してもらえても、今は忙しいから余裕のあるときにやろうと言って後回しになることはよくある話です。ビジネス的なメリットとしてはアカウントデータが漏洩した際に危険がなくなるという点があるのですが、そもそもデータ漏洩しないようにしろよと混ぜっ返したことを言われてしまうのがオチです。そうじゃないんですけどね。

という感じで、昔からあるシステムで当時は妥当だったけど今はリスクのある設計のデータがある場合、そしてその対策をとろうにもマネジメント側にブロックされてしまって放置されている。そういうケースであると、2023年になってもソルトなしMD5というケースはあるだろうなぁと思いました。2023年に新規にソルトなしMD5で実装した場合には、さすがにプロとしてそれはどうよと石を投げたくなりますが、もろもろ事情があって放置されてしまっていた場合は、そういうこともあるよねぇと同情したくなります。まあ、データ漏洩されたユーザにとっては、そんな事情はどうでもいいことなんですけどね。

ところでこれを書いていて思いましたが、一般に脆弱性といってもいくつかの種類があるのかなと思いました。

一つは実装の脆弱性です。まあ、一種のバグですね。対策はプログラムを修正することです。サービスとして提供されている場合は提供側で一括して修正出来ますが、プログラムをユーザに配布する場合は修正版を行き渡らせるのがとても大変だったりはします。未だに何年も前のWindowsの脆弱性を突いたマルウェアがはびこっていたりしますしね。

次にあるのは規格の脆弱性です。規格の設計時に不備があった場合。この場合、規格上では対処できません。対処した新しい規格を策定し、旧版の規格を廃止するしかありません。SSLとかでは時々ありますよね。

そして最後にあるのがアルゴリズムの脆弱性。MD5の脆弱性もここにありますね。実装も規格も問題なかったんだけど、アルゴリズムが突破されてしまって脆弱になってしまったという。そしてこれ、今後も同じようなことが起こりえる可能性は常にあるんですよね。巨大な合成数の素因数分解が容易に行えるようになったら、RSA暗号は使えなくなってしまう。その危険性は常にありながら現在でもRSA暗号が使い続けられているわけです。

そして書きたかったことは、現在安全と思われているハッシュアルゴリズムも同様ですよねってことです。未来において容易に復元するアルゴリズムが発見されない保証はどこにもありません。というか、多分5年10年というスパンのなかでは発見される方が自然と思った方がいいですよね。そしてアルゴリズムの脆弱性が発見されてしまったら、現在は安全と思われていたシステムが、ソルトなしMD5を採用していたシステムと同様に危険になってしまう。今安全と思われているアルゴリズムも未来においては危険かもしれないので、常にアルゴリズムの乗り換えを考慮しておかないといけないって話かなと思ったわけです。俺のシステムはソルトなしMD5なんて使ってないから安全だぜ、ってあぐらをかいてる人は、その辺どうなんでしょうねってことかなと思いました。

あ、念のために補足しておくと、今回情報漏洩をしたサービスが何年前からあるサービスなのかは知りません。軽くググったけど情報見つけられなかったのと、漏洩したサービスを擁護したいのが趣旨ではないから。現時点で最新のセキュリティ技術も5年10年経てば脆弱性があらわになる可能性があって、常にその追随が出来てるとは限らないよねって話が趣旨なので。そりゃ正論としては常に追随するべきなんですがね。