この記事に関連するツール
ブラウザ上ですぐに試せます。記事の内容を確認しながら使うと、作業の流れをつかみやすくなります。

「パスワードを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)を使います。