java-recipes

ホーム エンコーディング・圧縮 › E-01

E-01: Base64 エンコーディング・デコーディング

java.util.Base64(Java 8+)を使ったエンコード・デコードを解説します。 標準・URL セーフ・MIME の3種類の使い分けと、バイナリデータの往復変換を紹介します。

いつ使うか

  • 画像やバイナリデータをテキストとして JSON・XML に埋め込むとき
  • Basic 認証のヘッダー(Authorization: Basic {base64})を生成するとき
  • JWT(JSON Web Token)のペイロード部分をデコードして中身を確認するとき
  • URL の中でバイナリデータやトークンを安全に渡すとき(URL セーフ Base64)

Base64 エンコーダーの種類

種類取得方法用途・特徴
標準(RFC 4648)Base64.getEncoder()一般的な用途。+・/・= を使用
URL セーフBase64.getUrlEncoder()URL・ファイル名に使用可能。+→- /→_
MIMEBase64.getMimeEncoder()メール添付に使用。76文字ごとに改行

サンプルコード

Base64EncodingSample.java
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class Base64EncodingSample {

    // 文字列を Base64 エンコード
    public static String encode(String text) {
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        return Base64.getEncoder().encodeToString(bytes);
    }

    // Base64 をデコード
    public static String decode(String encoded) {
        byte[] bytes = Base64.getDecoder().decode(encoded);
        return new String(bytes, StandardCharsets.UTF_8);
    }

    // URL セーフ Base64 エンコード(+→- /→_ パディングなし)
    public static String encodeUrlSafe(String text) {
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
    }

    // URL セーフ Base64 デコード
    public static String decodeUrlSafe(String encoded) {
        byte[] bytes = Base64.getUrlDecoder().decode(encoded);
        return new String(bytes, StandardCharsets.UTF_8);
    }

    // バイナリデータのエンコード・デコード例
    public static void binaryExample() {
        byte[] binaryData = {0x00, 0x01, 0x02, (byte) 0xFF, (byte) 0xFE};
        String encoded = Base64.getEncoder().encodeToString(binaryData);
        System.out.println("バイナリ→Base64: " + encoded);

        byte[] decoded = Base64.getDecoder().decode(encoded);
        System.out.println("一致確認: " + Arrays.equals(binaryData, decoded));
    }

    public static void main(String[] args) {
        String original = "Hello, java-recipes! 日本語テスト";
        String encoded = encode(original);
        String decoded = decode(encoded);

        System.out.println("元の文字列: " + original);
        System.out.println("エンコード: " + encoded);
        System.out.println("デコード:   " + decoded);
        System.out.println("一致:       " + original.equals(decoded));

        System.out.println("\n--- URL セーフ ---");
        String urlSafe = encodeUrlSafe("test/path?key=value&other=123");
        System.out.println("URL セーフ: " + urlSafe);
        System.out.println("デコード:   " + decodeUrlSafe(urlSafe));

        System.out.println("\n--- バイナリ ---");
        binaryExample();
    }
}

Java 8 から java.util.Base64 が標準ライブラリに追加されました。それ以前は Apache Commons Codec 等の外部ライブラリが必要でした。

よくあるミス・注意点

⚠️ Base64 は暗号化ではない

Base64 はエンコーディング(変換)であり、暗号化ではありません。エンコードされたデータは誰でもBase64.getDecoder().decode()で簡単にデコードできます。パスワードやシークレットキーを Base64 で「隠す」のは誤りです。

⚠️ URL の中では必ず URL セーフ Base64 を使う

標準 Base64 の +/ は URL の中で特殊な意味(スペース・パス区切り)を持ちます。 URL クエリパラメータやパスにトークンを含める場合は Base64.getUrlEncoder() を使ってください。

⚠️ パディング文字 = が問題になる場合は withoutPadding()

Base64 エンコード後の末尾に付く = はパディング文字です。URL やファイル名で問題になる場合は .withoutPadding() で省略できます。デコード時は getUrlDecoder() はパディングなしのデータも自動的に処理します。

⚠️ Java 7 以前は外部ライブラリが必要だった

java.util.Base64 は Java 8 で追加されました。古いコードでは非公開 API の sun.misc.BASE64Encoder や Apache Commons Codec が使われていることがあります。Java 8 以降のプロジェクトでは必ず java.util.Base64 を使いましょう。

テストする観点

  • エンコード → デコードで元の文字列と一致すること(往復変換)
  • バイナリデータのエンコード → デコードでバイト列が一致すること
  • 空文字列("")をエンコード・デコードしても例外が発生しないこと(境界値)
  • マルチバイト文字(日本語・絵文字)が正しくエンコード・デコードできること
  • URL セーフエンコードの結果に +/ が含まれないこと
  • 標準 Base64 と URL セーフ Base64 の結果が異なるデータで差異が出ること

GitHub でソースコードを見る →