【基本/応用技術者試験】暗号化とハッシュ化の違いとは?使い分けを初心者向けにわかりやすく解説

サムネイル画像 基本/応用情報技術者試験

今回は、基本情報技術者試験でもよく混同されやすい「暗号化とハッシュ化の違い」について解説していきます。

「暗号化とハッシュ化って、どちらも読めない形にする処理じゃないの?」
「パスワード保存ではどっちを使うの?」
「試験問題になると、いつも迷ってしまう…」

こんな疑問はありませんか?

この2つはどちらもセキュリティ分野で重要ですが、目的がまったく違います。
ここを整理できると、基本情報の問題でもかなり判断しやすくなります。

この記事を読み終えると、暗号化とハッシュ化の違いを初心者でもスッキリ説明できるようになると思いますので、ぜひ最後まで読んでいただけると嬉しいです。

基本情報で押さえるべき結論

まず結論からいうと、違いはとてもシンプルです。

  • 暗号化:元のデータを読めない形にするが、鍵を使えば元に戻せる
  • ハッシュ化:データを別の値に変換するが、基本的に元に戻せない

つまり、「復号できるかどうか」が最重要ポイントです。

基本情報では、この違いをもとに「パスワード保存に適切なのはどちらか」「改ざん検知に使うのはどちらか」といった形で問われやすいです。

暗号化とは?

暗号化とは、データを第三者に読まれないように変換する処理です。
ただし、正しい鍵を使えば復号して元の内容に戻せます。

たとえば、通信内容やファイルの中身のように、あとで元データを使いたい情報には暗号化が向いています。

イメージとしては、「読めない箱にしまって、鍵を持っている人だけが開けられる」感じです。

ハッシュ化とは?

ハッシュ化とは、データを一定の計算ルールで別の値に変換する処理です。
この変換後の値をハッシュ値と呼びます。

ハッシュ化の大事な特徴は、元のデータに戻せないことです。
そのため、パスワードのように「元の文字列そのものは保存しなくていいが、正しいかどうかは確認したい」場面でよく使われます。

また、元データが少しでも変わるとハッシュ値も大きく変わるため、改ざん検知にも向いています。

基本情報での覚え方

  • 暗号化=隠して、あとで戻す
  • ハッシュ化=変換して、照合する

迷ったら、「元に戻す必要があるか?」で考えるとかなり整理しやすいです。

なお、条件によって処理を分けるようなC++の基本文法がまだ不安な方は、if文とswitch文の使い分けの記事もあわせて読むと理解しやすいです。

C++で違いをイメージしてみよう

ここでは、暗号化は「戻せる」、ハッシュ化は「戻せない」という違いだけをつかむために、C++で簡単なサンプルを書いてみます。

※ハッシュの部分は学習用の簡易例です。実務では自作せず、信頼できる方式を使ってください。

▼main.cpp


#include <iostream>
#include <iomanip>
#include <string>

std::string xorEncrypt(const std::string& text, char key) {
    std::string result = text;
    for (char& c : result) {
        c ^= key;
    }
    return result;
}

unsigned int simpleHash(const std::string& text) {
    unsigned int value = 5381;
    for (unsigned char c : text) {
        value = ((value << 5) + value) + c;
    }
    return value;
}

void printHex(const std::string& text) {
    for (unsigned char c : text) {
        std::cout << std::hex << std::setw(2) << std::setfill('0')
                  << static_cast<int>(c) << " ";
    }
    std::cout << std::dec << "\n";
}

int main() {
    std::string original = "PASSWORD";
    char key = 0x0F;

    std::string encrypted = xorEncrypt(original, key);
    std::string decrypted = xorEncrypt(encrypted, key);

    std::cout << "[暗号化]\n";
    std::cout << "元データ: " << original << "\n";
    std::cout << "暗号化後(16進数): ";
    printHex(encrypted);
    std::cout << "復号後: " << decrypted << "\n\n";

    std::cout << "[ハッシュ化]\n";
    std::cout << "入力: " << original << "\n";
    std::cout << "ハッシュ値: " << simpleHash(original) << "\n";

    return 0;
}

実行結果

[暗号化]
元データ: PASSWORD
暗号化後(16進数): 5f 4e 5c 5c 58 40 5d 4b
復号後: PASSWORD

[ハッシュ化]
入力: PASSWORD
ハッシュ値: 3792532749

この例では、暗号化した文字列は鍵を使って元に戻せています。
一方でハッシュ化は、入力からハッシュ値を作るだけで、そこから元の文字列を取り戻すことはできません。

関数を分けたコードの読み方が不安なら、プロトタイプ宣言の記事もあわせて読むのがおすすめです。

【重要】私が実際に個人開発で困った体験談

以前、個人で小さなゲーム用ツールを作っていたとき、ログイン情報の扱いで失敗したことがあります。

当時は「見えなくして保存すれば安全だろう」と思って、パスワードを簡単な暗号化で保存していました。ですが、あとから見直すと、復号に必要な鍵も同じプログラム側に置いていて、これでは仕組みを追われたときに元のパスワードが読める可能性がありました。

そこで設計を見直して、パスワードはハッシュ化して保存、あとで内容を使う設定データだけを暗号化して保存する形に変更しました。
この経験から、「読めなくする」ではなく「何の目的で保存するか」で選ぶのが大事だと実感しました。

よくある失敗例と解決策

  • パスワード保存に暗号化を使ってしまう
    → パスワードは復号する必要がないので、基本はハッシュ化で考えます。
  • ハッシュ化すれば秘密にできると思ってしまう
    → ハッシュ化は「隠す」よりも「照合」や「改ざん検知」に向いた仕組みです。
  • 学習用サンプルをそのまま本番利用してしまう
    → サンプルコードは理解用です。実際の開発では、自作暗号や簡易ハッシュではなく、実績のある方式を使いましょう。

試験で迷ったときの判断ポイント

  • 通信内容を守る → 暗号化
  • パスワードを保存して照合する → ハッシュ化
  • データが改ざんされていないか確認する → ハッシュ化
  • あとで元の内容を取り出したい → 暗号化

この4つを押さえておくと、基本情報の問題でもかなり強くなります。

変数の扱いがまだ不安な方は、変数の初期化 =0 と {0} の違いも読んでおくと、C++コードが追いやすくなります。

まとめ

  • 暗号化は鍵を使って元に戻せる
  • ハッシュ化は基本的に元に戻せない
  • 暗号化は通信内容やファイル保護に向いている
  • ハッシュ化はパスワード照合や改ざん検知に向いている
  • 「復号が必要かどうか」で考えると整理しやすい
  • 基本情報では用途の違いをセットで覚えるのが重要

関連記事