WebアプリケーションにおけるAES対称暗号化とMD5ハッシュの実践ガイド

Webサービスで機密データを守るためには、適切な暗号技術を選び、正しく実装することが不可欠である。本稿では、ブラウザ⇄サーバー間でよく使われる「AESによる可逆暗号化」と「MD5による不可逆ハッシュ」の使い分けと実装例を示す。

1. AES 共通鍵暗号のフロー実装

フロントエンドでパスワードを暗号化し、バックエンドで復号する典型的な手順は次の通り。

1.1 クライアントサイド(JavaScript)

<!-- 暗号化ライブラリの読み込み -->
<script src="/static/crypto-js.min.js"></script>

<script>
function encryptPassword(rawPass) {
  const key = CryptoJS.enc.Utf8.parse('my-secret-key-16'); // 16バイト鍵
  const iv  = CryptoJS.enc.Utf8.parse('initial-vector16'); // 初期化ベクトル
  return CryptoJS.AES.encrypt(rawPass, key, { iv: iv }).toString();
}

document.getElementById('loginForm').addEventListener('submit', (e) => {
  e.preventDefault();
  const plain = document.getElementById('pwd').value;
  document.getElementById('pwd').value = encryptPassword(plain);
  e.target.submit();
});
</script>

1.2 サーバーサイド(Spring Boot)

@Service
public class AesCryptoService {
    private static final String ALGO = "AES/CBC/PKCS5Padding";
    private static final byte[] KEY  = "my-secret-key-16".getBytes(StandardCharsets.UTF_8);
    private static final byte[] IV   = "initial-vector16".getBytes(StandardCharsets.UTF_8);

    public String decrypt(String base64Cipher) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGO);
        SecretKeySpec keySpec = new SecretKeySpec(KEY, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(IV);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

        byte[] decoded = Base64.getDecoder().decode(base64Cipher);
        byte[] plain   = cipher.doFinal(decoded);
        return new String(plain, StandardCharsets.UTF_8);
    }
}

2. MD5 ハッシュの簡易利用例

ファイルチェックサムやキャッシュキー生成など、セキュリティ要件が低い用途であれば MD5 を用いることができる。ただしパスワード保存には絶対に使用しない。

import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;

public class ChecksumUtil {
    public static String toMd5Hex(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(text.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : hash) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        System.out.println(toMd5Hex("123")); // 202cb962ac59075b964b07152d234b70
    }
}

3. 実装上の注意点

  • AES鍵は環境変数や KMS(AWS KMS、HashiCorp Vault など)で管理し、ソースコードに直接記載しない。
  • MD5は衝突耐性が失われているため、セキュアな署名やパスワードストレージには PBKDF2、bcrypt、Argon2 などを選択する。
  • ブラウザ⇄サーバー間通信は HTTPS/TLS を必須とし、上記の暗号化は追加レイヤーとして位置づける。

タグ: AES MD5 CryptoJS Spring Boot 暗号化

5月17日 12:08 投稿