エンコード・ハッシュ・暗号化の違いのイメージ

「パスワードをBase64で保存しています」——これはセキュリティ上の重大な誤解です。エンコード・ハッシュ・暗号化はどれも文字列を別の形に変換しますが、目的はまったく異なります。混同するとデータ漏洩や不具合につながります。

この記事では、3つの違いを比較表と具体例で整理し、「どの場面でどれを使うべきか」をはっきりさせます。

まず結論:3つの違い

目的元に戻せる?鍵が必要?代表例
エンコードデータを別の表現形式に変換はい(誰でも)不要Base64, URLエンコード
ハッシュ固定長の指紋を作る(一方向)いいえ不要SHA-256, HMAC
暗号化秘密にして許可された人だけ復号はい(鍵があれば)必要AES, RSA

ポイントは、エンコードは秘匿性ゼロハッシュは元に戻せない暗号化だけが「秘密を守る」ための仕組みということです。

エンコード:可読性・互換性のための変換

エンコードは、データを「別の表現方法」に置き換えるだけです。鍵もパスワードも要らず、誰でも元に戻せます。秘匿の機能は一切ありません。

例えばBase64は、バイナリや特殊文字をテキストとして安全に運ぶための方式です。

Hello, World!   →(Base64エンコード)→   SGVsbG8sIFdvcmxkIQ==

SGVsbG8sIFdvcmxkIQ== は一見ランダムに見えますが、Base64変換ツールに貼れば誰でも瞬時に元の文字列へ戻せます。URLに日本語や記号を載せるためのURLエンコードも同じ仲間です。

よくある誤用: APIキーやパスワードをBase64にして「隠した」つもりになるのは危険です。Base64は暗号化ではないため、秘匿には一切役立ちません。

ハッシュ:一方向の「指紋」

ハッシュは、入力データから固定長の値(ダイジェスト)を計算する一方向の変換です。同じ入力からは必ず同じ値が出ますが、ハッシュ値から元のデータを復元することはできません。

password123   →(SHA-256)→   ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f

入力が少しでも変わると、出力は大きく変わります。この性質から、ハッシュは次の用途に使います。

  • パスワードの保存: 平文ではなくハッシュを保存し、ログイン時は入力値のハッシュと突き合わせる(実際にはソルト+bcrypt/Argon2などを使う)。
  • 改ざん検知・整合性チェック: ファイルやメッセージのハッシュを比較し、内容が変わっていないか確認する。
  • 署名の一部: JWTの署名やHMACで、データが改ざんされていないことを保証する。

ハッシュ生成ツールでSHA-256やHMACを試すと、入力を変えたときに出力が一変する様子を確認できます。

重要: ハッシュは「元に戻せない」のが本質です。だからこそパスワード保存に向きます。逆に、後で元データが必要になる用途には使えません。

暗号化:鍵で守る、戻せる秘密

暗号化は、鍵を使ってデータを読めない形に変換し、正しい鍵を持つ人だけが復号できる仕組みです。エンコードと違って鍵がなければ戻せず、ハッシュと違って(鍵があれば)戻せます。これが「秘密を守る」唯一の方法です。

  • 共通鍵暗号(AESなど): 暗号化と復号に同じ鍵を使う。高速で、保存データの暗号化などに使う。
  • 公開鍵暗号(RSAなど): 公開鍵で暗号化し、秘密鍵で復号する。鍵交換やデジタル署名に使う。

HTTPS通信、データベースの保存時暗号化、機密ファイルの保護などはすべて暗号化の領域です。鍵の管理(漏らさない・適切に保管する)がそのまま安全性を左右します。

使い分けの早見表

やりたいこと使うもの
URLやJSONに特殊文字を安全に載せたいエンコード(Base64 / URLエンコード)
パスワードを安全に保存したいハッシュ(bcrypt / Argon2、ソルト付き)
ファイルが改ざんされていないか確認したいハッシュ(SHA-256)
データを後で元に戻せる形で秘密にしたい暗号化(AES / RSA)
通信内容を盗聴から守りたい暗号化(TLS/HTTPS)
トークンが改ざんされていないか検証したいハッシュベースの署名(HMAC / JWT)

やりがちな失敗

  • Base64で「暗号化したつもり」: 前述のとおり秘匿性はゼロです。機密情報の保護には使えません。
  • パスワードを暗号化して保存: 復号できる=鍵が漏れれば全パスワードが露出します。パスワードは復号不要なので、ハッシュ(ソルト付き)が正解です。
  • 単純なSHA-256だけでパスワード保存: 高速すぎて総当たりに弱く、レインボーテーブル攻撃も受けます。ソルトと、bcrypt/Argon2のような意図的に遅いアルゴリズムを使います。
  • 自前で暗号アルゴリズムを実装: 暗号は「枯れた標準ライブラリ」を使うのが鉄則。独自実装はほぼ確実に脆弱になります。

まとめ

3つは名前が似ていても役割が正反対です。エンコードは見た目を変えるだけ(秘匿しない)、ハッシュは戻せない指紋、暗号化は鍵で守る戻せる秘密。この区別さえ押さえれば、「パスワードはハッシュ、通信は暗号化、URL用途はエンコード」と自然に選べるようになります。手元で挙動を確かめたいときは、Base64変換ハッシュ生成JWTデコードを実際に触ってみてください。

よくある質問

Base64はなぜ暗号化ではないのですか?

Base64は鍵を使わず、変換ルールが公開されているため、誰でも瞬時に元へ戻せます。秘匿の要素が一切ないため「暗号化」ではなく「エンコード(表現形式の変換)」に分類されます。機密情報を隠す目的には使えません。

パスワードはハッシュと暗号化のどちらで保存すべきですか?

ハッシュです。パスワードは「後で復号する必要がない」ため、一方向のハッシュ(ソルト付きのbcryptやArgon2)が適切です。暗号化で保存すると、復号鍵が漏れた時点で全パスワードが露出するリスクがあります。

ハッシュは絶対に元に戻せないのですか?

計算上、ハッシュ値から元データを逆算することはできません。ただし、よくあるパスワードは事前計算(レインボーテーブル)で照合される恐れがあります。だからこそ、ユーザーごとに異なるソルトを加え、総当たりに強い遅いアルゴリズムを使うことが重要です。

JWTのトークンは暗号化されていますか?

一般的なJWT(署名付きJWS)は暗号化ではなく署名です。ペイロードはBase64URLエンコードされているだけで、JWTデコードツールで誰でも中身を読めます。署名は改ざん検知のためのものなので、JWTに秘密情報をそのまま入れてはいけません。秘匿が必要な場合は暗号化(JWE)を使います。