メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
MySQL には MD5()、SHA1()、および SHA2() が組み込まれています。これらは動作しますが、16 進文字列を返します。SHA-256 ハッシュでは 64 文字になりますが、その実データは 32 バイトです。ハッシュをバイナリで保存するとサイズは半分になり、インデックスの効率も上がります。VillageSQL の vsql_crypto 拡張機能の digest() は生のバイナリを返し、すべてのアルゴリズムを 1 つの関数で扱えます。

MySQL のデフォルト: 分散した関数と 16 進出力

MySQL はハッシュ化のために 3 つの別々の関数を提供しています。
これらは動作しますが、ストレージに無駄があります。256 ビットの SHA2 は 64 文字の VARCHAR を返します。ハッシュの各バイトが 2 桁の 16 進数として符号化されるため、必要なバイト数の 2 倍です。バイナリ出力を得るには UNHEX(SHA2('hello', 256)) と書きます。これは動作しますが、毎回一貫して書くには煩雑です。 また、sha224 や sha384 の選択肢はありません。MySQL が公開しているものに限られます。

標準的な回避策: UNHEX + SHA2

コンパクトなバイナリ保存のために、開発者は SHA2() を UNHEX() で包みます。
これでコンパクトな保存ができます。少し冗長ですが、標準的な手法であり、SHA-256 と SHA-512 では問題なく動作します。

VillageSQL の場合: digest()

VillageSQL の vsql_crypto 拡張機能は digest(data, algorithm) を追加します。この関数は VARBINARY のハッシュを直接返すため、UNHEX() で包む必要がありません。
ログや表示のために読める文字列が必要な場合は HEX() を使います。

サポートされるアルゴリズム

新しいアプリケーションでは MD5 や SHA-1 を使わないでください。どちらにも既知の衝突脆弱性があります。ほとんどの用途では SHA-256 が実用的なデフォルトです。 パスワードの保存に限っては、digest() は適切なツールではありません。crypt() と gen_salt() については MySQL でのパスワードのハッシュ化を参照してください。

各手法を使う場面

VillageSQL 上の新しいプロジェクトでは、digest() のほうが簡潔な選択です。既存の MySQL のみのアプリケーションでは、UNHEX(SHA2()) も同じく正しい選択です。

よくある質問

digest() と SHA2() の違いは何ですか?

SHA2('hello', 256) は 64 文字の 16 進文字列を返します。digest('hello', 'sha256') は 32 バイトの VARBINARY を返します。計算されるハッシュは同じで、違いは符号化です。バイナリ保存のほうがコンパクトで、インデックスの作成も高速です。

digest() で重複行を検出できますか?

はい。digest(content, 'sha256') をインデックス付きの列に保存し、WHERE sha256 = digest(incoming_content, 'sha256') で問い合わせます。これは、アップロードされたファイルの重複排除、変更されたレコードの検出、コンテンツアドレス指定の検索の構築でよく使われるパターンです。

digest() はパスワードに安全ですか?

いいえ。digest() は高速なハッシュであり、マイクロ秒で計算されます。パスワードのハッシュ化には、低速で反復するアルゴリズムが必要です。同じ拡張機能の crypt() と gen_salt() を使ってください。MySQL でのパスワードのハッシュ化を参照してください。

digest() は HMAC をサポートしていますか?

いいえ。digest() は鍵を持たないただのハッシュです。鍵付きの認証コードには hmac() を使います。MySQL での HMAC 署名を参照してください。

トラブルシューティング

関連項目