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 这个大坑。务必做好类型过滤!


原始标题:Listing the Available Cipher Algorithms