ハッシュを作る
入れたものはどこにも送りません。計算はこのブラウザの中だけで終わり、保存もしていません。 空のままでも計算します ── 0バイトにも答えはあるからです。
ファイルからも作れます20.0MBまで。選んだファイルもどこにも送りません
ファイルの中身を読むのはこのブラウザの中だけです。中身は、お使いのブラウザの中だけで処理しますので、配布されたファイルが途中で壊れていないかを、安心して確かめられます。
よくある質問
ハッシュとは何ですか?
どんなに長いものを入れても、決まった長さの短い印を返す計算のことです。SHA-256 なら、1文字でも1ギガバイトのファイルでも、答えは必ず16進64桁になります。同じものを入れれば必ず同じ答えになり、少しでも違えば全く別の答えになるので、「同じものかどうか」を短い文字だけで確かめられます。ファイルの指紋のようなものだと考えると分かりやすいです。
MD5 は作れませんか?
このページでは作れません。ブラウザが持っていないからです。ブラウザの暗号の機能(Web Cryptography API)の仕様書を全文取ってきて数えると、MD5 という語は1回も出てきません。載っているのは SHA-1・SHA-256・SHA-384・SHA-512 の4つだけです。外から部品を持ち込めば計算はできますが、このサイトは外の部品を読み込まない作りなので、その道は選んでいません。なお、よく使われていた CryptoJS という部品は、説明書の冒頭で「開発を終了した」と自ら書いています。理由は「いまはブラウザにも Node にも本物の暗号機能があるから」です。
同じ文字を入れたのに、別のところで見た答えと違います。
いちばん多い原因は、末尾の見えない文字です。文章をコピーしたときに改行が1つ付いてきていると、それも計算に入るので答えは全く別物になります。このページは、末尾に改行や空白があるときにその場で知らせます。次に多いのが文字コードの違いです。ハッシュは文字ではなくバイトを数えるので、同じ「あ」でも UTF-8(3バイト)と Shift_JIS(2バイト)では答えが変わります。このページは UTF-8 として数えています。
入れた文章やファイルは、どこかに送られていますか?
送っていません。計算はすべてあなたのブラウザの中で終わり、外へ出す処理は1行も書いていません。信じてもらう必要はなくて、自分で確かめられます。キーボードのF12(または右クリックから「検証」)で開発者ツールを開き、「ネットワーク」を選んだまま文字を打ってみてください。何も通信が増えないはずです。ファイルも同じで、選んだファイルは読み込まれるだけで、送信されません。
ハッシュが同じなら、中身も同じですか?
SHA-256 では、いまのところ同じ答えになる別々のものは見つかっていません。ですが SHA-1 では実際に見つかっています。2017年2月23日、CWIアムステルダムとGoogleの研究者が、見た目も中身も違うのに SHA-1 が完全に一致する2つのPDFを公開しました。どちらも 422,435 バイトで、SHA-1 はどちらも 38762cf7f55934b34d179ae6a4c80cadccbb7f0a です。SHA-256 で計算すると別々の答えになるので、確かに違うファイルだと確かめられます。
パスワードをハッシュにして保存すれば安全ですか?
それだけでは足りません。ハッシュは元に戻せませんが、同じパスワードからは必ず同じ答えが出るので、よくあるパスワードの答えを先に一覧にしておけば照合できてしまいます。しかも SHA-256 は速く計算できるように作られていて、攻める側にとってはそれが有利に働きます。米国の指針(NIST SP 800-63B)は、パスワードごとに違う塩(salt)を混ぜたうえで、わざと時間のかかる鍵導出関数を使うよう求めています。塩は32ビット以上、PBKDF2 なら繰り返し回数はサーバーが耐えられる限り大きく、目安として1万回以上とされています。
大きいファイルが計算できないのはなぜですか?
このページでは 20.0MB までにしています。ブラウザの計算機能は、データを少しずつ渡す使い方ができず、まとめて1つ受け取る決まりになっているからです。つまりファイル全体をいったん機器のメモリに載せることになります。上限を決めずに大きなファイルを受けると、古い機器では画面が固まってしまいます。上限は仕様で決まった数ではなく、このサイトが決めた自主的な数です。超えたときは途中まで計算するようなことはせず、理由を出して止めます。
文字やファイルから SHA-1 / SHA-256 / SHA-384 / SHA-512 の ハッシュ(データの指紋)を作ります。入れたものはどこにも送りません。計算はぜんぶ、いま開いているブラウザの中だけで終わります。
末尾の改行1つで、答えはまるごと別物になります
ここがハッシュのいちばん面白いところです。入力をほんの少し変えただけで、答えは似たものにならず、全く別物になります。「hello」と、その末尾に改行を1つ足しただけのものを見くらべてみてください。
- hello
- 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
- hello + 末尾に改行1つ
- 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
- Hello(H だけ大文字)
- 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
改行を1つ足しただけで、64桁のうち59桁が変わりました。 ビットで数えると、256ビットのうち126ビットです。 「H」を大文字にしただけのほうも61桁・125ビットが変わっています。 どちらもだいたい半分のビットがひっくり返っていることになります。
「全部の桁が変わらないのはなぜ?」と思ったかもしれません。16進の1桁は16通りしかないので、たまたま同じ字になる桁が出るからです。 64桁 ÷ 16通り = 平均4桁ほどは偶然そろう計算になります。 上の例でも、そろったのは5桁と3桁でした。ぴったり4桁の前後に落ち着くこと自体が、答えがでたらめに散っている証拠です。
この性質を雪崩効果(avalanche effect)といいます。 入力の1ビットの変化が、雪崩のように答え全体へ広がる、という意味です。半分ずつ変わるのが理想とされていて、 それより偏っていると「入力を少し変えたら答えも少し似ていた」という手がかりを 与えてしまいます。
「同じ文を入れたのに答えが違う」の原因は、ほとんどこれです。文章をコピーすると、見えない改行が末尾に付いてくることがあります。 上の道具は、末尾に改行や空白があるときにその場で知らせます。
1文字でも1ギガバイトでも、答えの長さは同じです
入れるものの大きさは、答えの長さに関係ありません。 SHA-256 なら必ず16進64桁です。何も入れなくても、64桁の答えが出ます。
- 何も入れない(0バイト)UTF-8 で0バイト
- e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85516進64桁
- 「a」1文字UTF-8 で1バイト
- ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb16進64桁
- 「abc」3文字UTF-8 で3バイト
- ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad16進64桁
- 「a」を100万回ならべたものUTF-8 で1,000,000バイト
- cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd016進64桁
ここで当然の疑問が出ます。入れるものは無限にあるのに、答えは有限なのだから、 いつかは同じ答えになる2つが必ずあるはずです。そのとおりで、 これを衝突といいます。避けられません。
では、なぜ使えるのか。数が多すぎて見つけられないからです。 256ビットの答えは 2の256乗通りあり、10進で書くと78桁になります。
115792089237316195423570985008687907853269984665640564039457584007913129639936どれくらいの大きさか、掛け算で確かめてみてください。1兆(1のうしろに0が12個)を6回かけ合わせても、まだこの数には届きません。1兆を6回かけると0が72個ですが、上の数は0が77個ぶんの大きさだからです。存在することと、見つけられることは別── ハッシュはこの差の上に成り立っています。
SHA-1 は「そのうち危ない」ではなく、すでに破られています
いまの話には続きがあります。SHA-1 では、その衝突が実際に見つかりました。2017年2月23日、オランダの CWI アムステルダムと Google の研究者が、中身の違う2つのPDFで、SHA-1 が完全に一致するものを公開しました。SHAttered(新しいタブで開きます)と名付けられた仕事で、その2つのファイルはいまも誰でも取ってきて確かめられます。
- 2つのファイルの大きさ
- どちらも422,435バイト別のファイルなのに、大きさまで同じに作られている
- SHA-1(2つとも同じ)
- 38762cf7f55934b34d179ae6a4c80cadccbb7f0a
- 1つ目の SHA-256
- 2bb787a73e37352f92383abe7e2902936d1059ad9f1ba6daaa9c1e58ee6970d0
- 2つ目の SHA-256
- d4488775d29bdef7993367d541064dbdda50d383f89f0aa13a6ff2e0894ba5ff
SHA-256 が違うことが、「本当に別のファイルだ」という証拠になっています。 同じファイルなら、どちらの方式でも答えは一致するはずだからです。 上の値は書き写したものではなく、2つのPDFを実際に取ってきて計算しました。
この衝突を作るには、SHA-1 の計算をおよそ900京回 (9のうしろに0が18個)繰り返す必要があり、のべ6,500年ぶんのCPUと110年ぶんのGPUが使われました。 当時としては手の届きにくい費用でしたが、計算機は年々安くなるので、費用は下がる一方です。
アメリカの標準を決める NIST は、2022年12月15日に「SHA-1 を退役させる」と発表し、2030年12月31日までに使うのをやめるよう求めています。 それでも SHA-1 をこのページに残してあるのは、 古いファイルの確認に今も出てくるからです。 選ぶと警告が出るようにしてあります。
元に戻せません。でも、パスワードをそのまま入れてはいけません
ハッシュは一方通行です。答えから元の文字を計算で求める方法は 見つかっていません。だから「パスワードそのものを預からずに、答えだけ保存しておけばよい」 という使い方が生まれました。 ここまでは正しい考え方です。
ところが、それだけでは足りません。ハッシュには同じものからは必ず同じ答えが出るという性質があります。 つまり、よくあるパスワードの答えを先に一覧表にしておけば、 保存された答えと照らし合わせるだけで元のパスワードが分かってしまいます。
さらに悪いことに、SHA-256 は速く計算できるように作られています。 速いことは本来の用途では長所ですが、片端から試す側にとっても長所になります。 いまの機械は1秒に何十億回も試せます。
だからアメリカの指針(NIST SP 800-63B の 5.1.1.2(新しいタブで開きます))は、こう求めています。
- 塩(salt)を混ぜる ── 人ごとに違う値を足してから計算する。同じパスワードでも答えが変わるので、一覧表が効かなくなる。塩は32ビット以上
- わざと時間のかかる計算にする ── PBKDF2 のような鍵導出関数を使い、何度も繰り返す。PBKDF2 なら1万回以上が目安(サーバーが耐えられる限り多く)
このページの答えを、そのままパスワードの保存に使わないでください。ハッシュは材料であって、パスワードの保存はその材料の使い方の話です。
始まりの数は、素数の平方根から来ています
SHA-256 の計算は、8つの決まった数から始まります。 この数がどこから来たのかを見ると、暗号の作り方の考え方が分かります。
| 何番目の素数か | 素数 | 平方根の小数部分の先頭32ビット |
|---|---|---|
| 1番目 | 2 | 6a09e667 |
| 2番目 | 3 | bb67ae85 |
| 3番目 | 5 | 3c6ef372 |
| 4番目 | 7 | a54ff53a |
| 5番目 | 11 | 510e527f |
| 6番目 | 13 | 9b05688c |
| 7番目 | 17 | 1f83d9ab |
| 8番目 | 19 | 5be0cd19 |
たとえば1行目。2の平方根は 1.41421356… です。 小数部分の 0.41421356… を2進数で書いて、先頭32ビットを取り出して16進にすると6a09e667 になります。 手順を知っていれば、誰でも同じ数を作れます。
これが大事なところです。 暗号の中に出てくる数は、作った人が好きに選んだ数であってはいけません。 弱くなる数をこっそり仕込めてしまうからです。 素数の平方根のように誰でも同じ手順で再現できる数を使えば、「袖の中に何も隠していない」ことを 示せます。こうして選ばれた数はナッシング・アップ・マイ・スリーブ数(nothing-up-my-sleeve number・手品師が袖に何も隠していないことを見せる仕草から)と 呼ばれています。
計算の途中で足していく64個の定数も同じ作り方ですが、そちらは平方根ではなく立方根です。 最初の4つは 428a2f98・71374491・b5c0fbcf・e9b5dba5(2・3・5・7の立方根)です。
この再現はこのサイトの中でも実際にやっています。素数と根の種類だけから値を作り直す関数を書き、FIPS 180-4 に載っている8つの値と一致するかを単体テストが毎回確かめています。 書き写した数ではない、ということを機械に見張らせています。
文字ではなく、UTF-8 のバイトを数えています
ハッシュはバイトの列に対する計算です。文字は直接扱えないので、 いったんバイトに直す必要があります。ここで、どの文字コードを使ったかによって答えが変わります。
- 「あ」を UTF-8 で書くと e3 81 82 の3バイト
- 「あ」を Shift_JIS で書くと 82 a0 の2バイト
同じ「あ」でも、渡すバイトが違えば当然ハッシュも別物になります。だからこのページは「UTF-8 として計算しています」と画面に書いています。ブラウザに入っている変換の道具(TextEncoder)は UTF-8 しか作らないと決まっているので、 ここで迷う余地はありません。 別の答えが出てくるときは、相手側が別の文字コードで 計算している可能性があります。
ファイルに上限があるのは、少しずつ渡せないからです
ブラウザの計算機能は、データをまとめて1つ受け取る形しか用意されていません。 少しずつ流し込んで最後に答えをもらう、という使い方ができないのです。 つまりファイル全体をいったんメモリに載せることになります。
そこでこのページは上限を20.0MBにしています。これは仕様で決まった数ではなく、このサイトが決めた数です。 超えたときは、途中まで計算するようなことはせず、理由を出して止めます── 途中までの答えは、正しい答えの一部にすらならないからです。
出どころ: 使える方式の一覧と secure context(https でしか使えない決まり)は W3C Web Cryptography API(新しいタブで開きます)(MD5 の語が0回であることは全文を取得して数えた)。 始まりの値と定数の作り方は FIPS 180-4(新しいタブで開きます)の 5.3.3 節と 4.2.2 節。 SHA-1 の退役は NIST の発表(2022年12月15日)、衝突の現物は SHAttered(新しいタブで開きます)(2つのPDFを実際に取得して計算)。 パスワードの保存の指針は NIST SP 800-63B。 画面に出している16進の値は、4方式ぶんすべて単体テストが ブラウザと同じ計算で作り直して突き合わせています。