1. 概述
在本篇教程中,我们将深入了解 Java 中的 Cipher
类,并学习如何列出当前环境中所有可用的加密算法及其对应的提供者(Provider)。
2. Cipher 类简介
Cipher
类位于 javax.crypto
包中,是 Java 加密扩展(Java Cryptography Extension,简称 JCE)框架的核心组件。它提供了用于数据加解密、签名、消息摘要等多种密码学操作的基础支持。
3. 列出所有可用的加密算法
我们可以通过调用 Cipher.getInstance()
静态方法并传入指定的转换名称(transformation)来创建一个 Cipher
实例:
Cipher cipher = Cipher.getInstance("AES");
但在某些场景下,我们可能需要获取系统中所有支持的加密算法列表,比如确认某个特定算法是否在当前运行环境中可用。
为此,我们可以先获取所有注册的安全提供者(Provider),然后遍历每个 Provider 提供的服务(Service):
for (Provider provider : Security.getProviders()) {
for (Provider.Service service : provider.getServices()) {
String algorithm = service.getAlgorithm();
// ...
}
}
输出的部分算法名称如下:
SHA3-224
NONEwithDSA
DSA
JavaLoginConfig
DSA
SHA3-384
SHA3-256
SHA1withDSA
...
⚠️ 注意:并非所有列出的算法都可以作为 Cipher 的 transformation 使用。例如,尝试使用 SHA3-224
(一种哈希算法)实例化 Cipher 会导致异常:
Cipher cipher = Cipher.getInstance("SHA3-224");
抛出的异常信息如下:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting SHA3-224
✅ 正确的做法是:只筛选出类型为 "Cipher" 的服务。我们可以使用 Java Stream API 来优雅地完成这个任务:
List<String> algorithms = Arrays.stream(Security.getProviders())
.flatMap(provider -> provider.getServices().stream())
.filter(service -> "Cipher".equals(service.getType()))
.map(Provider.Service::getAlgorithm)
.collect(Collectors.toList());
筛选后的结果大致如下:
AES_192/CBC/NoPadding
AES_192/OFB/NoPadding
AES_192/CFB/NoPadding
AESWrap_192
PBEWithHmacSHA224AndAES_256
AES_192/ECB/NoPadding
AES_192/GCM/NoPadding
ChaCha20-Poly1305
PBEWithHmacSHA384AndAES_128
AES_128/ECB/NoPadding
AES_128/OFB/NoPadding
AES_128/CBC/NoPadding
...
这些才是真正可以用于 Cipher.getInstance()
的合法算法名称。
4. 小结
本文我们首先介绍了 Cipher
类的基本作用,然后演示了如何动态获取 JVM 环境中所有可用的加密算法,并通过过滤保留真正可用于加解密的算法列表。
一如既往,文中示例代码可在 GitHub 上获取:core-java-security-algorithms
📌 踩坑提醒:不要把所有 Service
都当成 Cipher
使用,否则会踩到 NoSuchAlgorithmException
这个大坑。务必做好类型过滤!