Base64 不是一种加密算法,而是一种编码方案。

- 编码 vs 加密:
- 编码:是一种将数据从一种格式转换为另一种格式的可逆过程,它不涉及密钥,目的是为了数据的表示、传输或存储,Base64 就是将二进制数据转换为纯文本字符串。
- 加密:是一种将数据转换为密文的过程,目的是为了保护数据的机密性,它需要一个密钥,没有正确的密钥就无法(或极难)还原原始数据。
当我们说“Base64 加密解密”时,更准确的说法是 Base64 编码和解码,它的主要用途是让二进制数据(如图片、文件、字节流)能够安全地在只支持文本的协议(如 HTTP、SMTP)中传输。
Java 8 及更高版本 (推荐)
从 Java 8 开始,Java 标准库 java.util.Base64 提供了强大且易用的 Base64 工具类,这是目前最推荐的方式。
核心类:java.util.Base64
这个类提供了两种编码器/解码器:
- 基本型:使用标准的 Base64 字母表,不添加任何换行符,适用于在 URL 或文件名等场景中使用。
- URL 和 Filename 安全型:使用一个修改过的字母表,将 替换为 ,将 替换为
_,这样可以避免在 URL 或文件名中产生歧义,这是处理 Web 资源链接时的首选。
编码和解码示例
下面是一个完整的示例,展示了如何使用 java.util.Base64 对字符串进行编码和解码。

import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Java8Base64Example {
public static void main(String[] args) {
// 1. 准备要编码的原始字符串
String originalString = "Hello, Java 8 Base64! 这是一个测试。";
// --- 基本型 Base64 编码和解码 ---
System.out.println("--- 基本型 Base64 ---");
// 获取基本型编码器
Base64.Encoder encoder = Base64.getEncoder();
// 将原始字符串转换为字节数组,然后进行编码
String encodedString = encoder.encodeToString(originalString.getBytes(StandardCharsets.UTF_8));
System.out.println("编码后: " + encodedString);
// 获取基本型解码器
Base64.Decoder decoder = Base64.getDecoder();
// 将 Base64 字符串解码为字节数组,然后转换回字符串
byte[] decodedBytes = decoder.decode(encodedString);
String decodedString = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println("解码后: " + decodedString);
System.out.println("解码是否成功: " + originalString.equals(decodedString));
System.out.println("-----------------------------------\n");
// --- URL 和 Filename 安全型 Base64 编码和解码 ---
System.out.println("--- URL 和 Filename 安全型 Base64 ---");
// 获取 URL 安全型编码器
Base64.Encoder urlEncoder = Base64.getUrlEncoder();
String urlEncodedString = urlEncoder.encodeToString(originalString.getBytes(StandardCharsets.UTF_8));
System.out.println("URL 编码后: " + urlEncodedString);
// 获取 URL 安全型解码器
Base64.Decoder urlDecoder = Base64.getUrlDecoder();
byte[] urlDecodedBytes = urlDecoder.decode(urlEncodedString);
String urlDecodedString = new String(urlDecodedBytes, StandardCharsets.UTF_8);
System.out.println("URL 解码后: " + urlDecodedString);
System.out.println("URL 解码是否成功: " + originalString.equals(urlDecodedString));
System.out.println("-----------------------------------\n");
}
}
运行结果:
--- 基本型 Base64 ---
编码后: SGVsbG8sIEphdmEgOiBCYXNlNjQhIOeUu+S4gOS4quWbvueJhTw==
解码后: Hello, Java 8 Base64! 这是一个测试。
解码是否成功: true
-----------------------------------
--- URL 和 Filename 安全型 Base64 ---
URL 编码后: SGVsbG8sIEphdmEgOyBCYXNlNjQhIOeUu+S4gOS4quWbvueJhTw==
URL 解码后: Hello, Java 8 Base64! 这是一个测试。
URL 解码是否成功: true
-----------------------------------
注意: 你会看到基本型和 URL 安全型的编码结果几乎一样,这是因为原始字符串中没有包含 或 这两个需要被替换的字符,如果你的原始二进制数据中恰好有这些字符,两种方式的区别就会体现出来。
处理字节数组(byte[])
除了直接处理字符串,Base64 更常用于处理二进制数据,如图片文件。
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
public class Base64FileExample {
public static void main(String[] args) throws IOException {
// 1. 读取一个图片文件为字节数组
Path imagePath = Paths.get("path/to/your/image.png"); // 替换成你的图片路径
byte[] imageBytes = Files.readAllBytes(imagePath);
// 2. 将图片字节数组编码为 Base64 字符串
Base64.Encoder encoder = Base64.getEncoder();
String base64Image = encoder.encodeToString(imageBytes);
System.out.println("图片 Base64 编码成功,长度: " + base64Image.length());
// 3. 将 Base64 字符串解码回字节数组
Base64.Decoder decoder = Base64.getDecoder();
byte[] decodedImageBytes = decoder.decode(base64Image);
// 4. 将解码后的字节数组写回一个新的文件,以验证是否成功
Path outputPath = Paths.get("output_image.png");
Files.write(outputPath, decodedImageBytes);
System.out.println("图片已成功解码并保存为 output_image.png");
}
}
Java 8 之前 (不推荐,但需了解)
在 Java 8 之前,开发者通常使用第三方库,最著名的是 Apache Commons Codec。

添加依赖
如果你使用 Maven,需要在 pom.xml 中添加依赖:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version> <!-- 使用最新的稳定版本 -->
</dependency>
使用 org.apache.commons.codec.binary.Base64
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
public CommonsCodecExample {
public static void main(String[] args) {
String originalString = "Hello, Apache Commons Codec!";
// 编码
byte[] encodedBytes = Base64.encodeBase64(originalString.getBytes(StandardCharsets.UTF_8));
String encodedString = StringUtils.newStringUtf8(encodedBytes); // 将字节数组转回字符串
System.out.println("编码后: " + encodedString);
// 解码
byte[] decodedBytes = Base64.decodeBase64(encodedString);
String decodedString = StringUtils.newStringUtf8(decodedBytes);
System.out.println("解码后: " + decodedString);
System.out.println("解码是否成功: " + originalString.equals(decodedString));
}
}
为什么不推荐?
- 增加外部依赖:需要引入第三方库,增加了项目的复杂性和体积。
- Java 8 已内置:Java 8 之后,标准的
java.util.Base64已经足够强大和高效,没有必要再使用第三方库。
总结与最佳实践
| 特性 | Java 8+ java.util.Base64 |
Apache Commons Codec |
|---|---|---|
| 依赖 | 无外部依赖,JDK 自带 | 需要添加 commons-codec 依赖 |
| 易用性 | API 设计直观,Encoder/Decoder 模式清晰 |
API 也非常成熟,使用广泛 |
| 功能 | 提供基本型和 URL 安全型 | 功能更丰富,如 Base64 等多种编码方式 |
| 推荐度 | 强烈推荐 (新项目必须使用) | 仅用于维护旧项目或需要特定功能时 |
核心要点:
- 理解 Base64 是编码,不是加密,它不提供安全性,任何获得 Base64 字符串的人都可以轻松解码。
- 优先使用 Java 8 的
java.util.Base64,这是现代 Java 开发的标准。 - 处理文本时:始终指定字符集(如
StandardCharsets.UTF_8),以避免在不同平台间产生乱码。 - 处理二进制数据(如文件)时:直接操作
byte[]数组,效率更高。 - 在 URL 中使用时:务必选择 URL 和 Filename 安全型 的编码器 (
Base64.getUrlEncoder()),以避免特殊字符导致的问题。
