我为此搜索过高低,但我似乎无法得到正确答案。
在Java中,可用的MessageDigests由您已配置/安装的安全提供程序确定。但假设只安装了一个普通的JDK8(在我的情况下为1.8.0_11),那么可用的哈希算法列表是什么?从文档中的示例中可以看出,它显而易见的是MD5,SHA1和SHA-256,但我似乎无法获得完整,权威的列表。
此列表是否存在,或者如何查找我的特定安装?
答案 0 :(得分:25)
除了JB的答案之外,我还想提出一个解决方案来查询运行时的可用算法。此方法当然可以轻松转换为Cipher
,SecureRandom
,Mac
,KeyAgreement
,KeyFactory
或任何其他类型的方法算法。
import java.security.MessageDigest;
import java.security.Provider;
import java.security.Provider.Service;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ShowHashAlgorithms {
private static final void showHashAlgorithms(Provider prov, Class<?> typeClass) {
String type = typeClass.getSimpleName();
List<Service> algos = new ArrayList<>();
Set<Service> services = prov.getServices();
for (Service service : services) {
if (service.getType().equalsIgnoreCase(type)) {
algos.add(service);
}
}
if (!algos.isEmpty()) {
System.out.printf(" --- Provider %s, version %.2f --- %n", prov.getName(), prov.getVersion());
for (Service service : algos) {
String algo = service.getAlgorithm();
System.out.printf("Algorithm name: \"%s\"%n", algo);
}
}
// --- find aliases (inefficiently)
Set<Object> keys = prov.keySet();
for (Object key : keys) {
final String prefix = "Alg.Alias." + type + ".";
if (key.toString().startsWith(prefix)) {
String value = prov.get(key.toString()).toString();
System.out.printf("Alias: \"%s\" -> \"%s\"%n",
key.toString().substring(prefix.length()),
value);
}
}
}
public static void main(String[] args) {
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
showHashAlgorithms(provider, MessageDigest.class);
}
}
}
此代码将为Java 1.8生成以下输出。请注意,由于API提供程序存在一些旧错误,因此提供程序版本仅作为double
出现。由于这个原因,无法区分版本1.80或版本1.8.0。
别名低于实际实现。其中一些别名为Object Identifiers或点符号中的OID。这些OID用于指示ASN.1编码数据格式内的算法,例如SSL / TLS中使用的X5.09v3证书。例如,1.3.14.3.2.26
是{iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) hashAlgorithmIdentifier(26)}
的点符号和SHA / SHA-1的别名。
--- Provider SUN, version 1.80 ---
Algorithm name: "MD2"
Algorithm name: "MD5"
Algorithm name: "SHA"
Algorithm name: "SHA-224"
Algorithm name: "SHA-256"
Algorithm name: "SHA-384"
Algorithm name: "SHA-512"
Alias: "SHA-1" -> "SHA"
Alias: "OID.1.3.14.3.2.26" -> "SHA"
Alias: "1.3.14.3.2.26" -> "SHA"
Alias: "OID.2.16.840.1.101.3.4.2.4" -> "SHA-224"
Alias: "OID.2.16.840.1.101.3.4.2.3" -> "SHA-512"
Alias: "OID.2.16.840.1.101.3.4.2.2" -> "SHA-384"
Alias: "OID.2.16.840.1.101.3.4.2.1" -> "SHA-256"
Alias: "2.16.840.1.101.3.4.2.4" -> "SHA-224"
Alias: "2.16.840.1.101.3.4.2.3" -> "SHA-512"
Alias: "2.16.840.1.101.3.4.2.2" -> "SHA-384"
Alias: "2.16.840.1.101.3.4.2.1" -> "SHA-256"
Alias: "SHA1" -> "SHA"
Bouncy Castle的输出(未被要求,包括用于比较):
--- Provider BC, version 1.51 ---
Algorithm name: "GOST3411"
Algorithm name: "MD2"
Algorithm name: "MD4"
Algorithm name: "MD5"
Algorithm name: "SHA-1"
Algorithm name: "RIPEMD128"
Algorithm name: "RIPEMD160"
Algorithm name: "RIPEMD256"
Algorithm name: "RIPEMD320"
Algorithm name: "SHA-224"
Algorithm name: "SHA-256"
Algorithm name: "SHA-384"
Algorithm name: "SHA-512"
Algorithm name: "SHA-512/224"
Algorithm name: "SHA-512/256"
Algorithm name: "SHA3-224"
Algorithm name: "SHA3-256"
Algorithm name: "SHA3-384"
Algorithm name: "SHA3-512"
Algorithm name: "Skein-256-128"
Algorithm name: "Skein-256-160"
Algorithm name: "Skein-256-224"
Algorithm name: "Skein-256-256"
Algorithm name: "Skein-512-128"
Algorithm name: "Skein-512-160"
Algorithm name: "Skein-512-224"
Algorithm name: "Skein-512-256"
Algorithm name: "Skein-512-384"
Algorithm name: "Skein-512-512"
Algorithm name: "Skein-1024-384"
Algorithm name: "Skein-1024-512"
Algorithm name: "Skein-1024-1024"
Algorithm name: "SM3"
Algorithm name: "TIGER"
Algorithm name: "WHIRLPOOL"
Alias: "SHA256" -> "SHA-256"
Alias: "SHA224" -> "SHA-224"
Alias: "1.3.36.3.2.3" -> "RIPEMD256"
Alias: "1.3.36.3.2.2" -> "RIPEMD128"
Alias: "1.3.36.3.2.1" -> "RIPEMD160"
Alias: "1.2.156.197.1.401" -> "SM3"
Alias: "SHA512" -> "SHA-512"
Alias: "SHA1" -> "SHA-1"
Alias: "GOST" -> "GOST3411"
Alias: "2.16.840.1.101.3.4.2.6" -> "SHA-512/256"
Alias: "2.16.840.1.101.3.4.2.5" -> "SHA-512/224"
Alias: "2.16.840.1.101.3.4.2.4" -> "SHA-224"
Alias: "2.16.840.1.101.3.4.2.3" -> "SHA-512"
Alias: "2.16.840.1.101.3.4.2.2" -> "SHA-384"
Alias: "2.16.840.1.101.3.4.2.1" -> "SHA-256"
Alias: "1.2.643.2.2.9" -> "GOST3411"
Alias: "1.3.14.3.2.26" -> "SHA-1"
Alias: "SHA512/224" -> "SHA-512/224"
Alias: "GOST-3411" -> "GOST3411"
Alias: "SHA512256" -> "SHA-512/256"
Alias: "SHA384" -> "SHA-384"
Alias: "SM3" -> "SM3"
Alias: "SHA" -> "SHA-1"
Alias: "1.2.840.113549.2.5" -> "MD5"
Alias: "1.2.840.113549.2.4" -> "MD4"
Alias: "1.2.840.113549.2.2" -> "MD2"
答案 1 :(得分:4)
要仅获取算法名称,而不使用别名或任何其他信息,最简单的方法是:
import java.security.Security;
import java.util.Set;
...
Set<String> algorithms = Security.getAlgorithms("MessageDigest");
自Java 1.4起
答案 2 :(得分:2)
文档说:
这些算法在Java加密体系结构标准算法名称文档
的MessageDigest部分中描述
linked document在目录后面包含以下行:
注意:Oracle Providers文档包含特定的提供者和算法信息。
linked document包含每个提供商提供的MessageDigest算法的完整列表。
答案 3 :(得分:2)
除了Maarten Bodewes的回答:我需要这样的算法,我写了一个方法,收集所有可用算法和别名的按名称排序列表。它使用java8的流API。请随时随地使用它。欢呼声。
public static List<String> getAvailableAlgorithms()
{
final String digestClassName = MessageDigest.class.getSimpleName();
final String aliasPrefix = "Alg.Alias." + digestClassName + ".";
return Arrays.stream(getProviders())
.flatMap(prov -> {
final Set<String> algorithms = new HashSet<>(0);
prov.getServices().stream()
.filter(s -> digestClassName.equalsIgnoreCase(s.getType()))
.map(Service::getAlgorithm)
.collect(Collectors.toCollection(() -> algorithms));
prov.keySet().stream()
.map(Object::toString)
.filter(k -> k.startsWith(aliasPrefix))
.map(k -> String.format("\"%s\" -> \"%s\"", k.substring(aliasPrefix.length()), prov.get(k).toString()))
.collect(Collectors.toCollection(() -> algorithms));
return algorithms.stream();
})
.sorted(String::compareTo)
.collect(Collectors.toList());
}
答案 4 :(得分:0)
一个班轮:
Arrays.stream(Security.getProviders())
.flatMap(provider -> provider.getServices().stream())
.filter(s -> MessageDigest.class.getSimpleName().equals(s.getType()))
.map(Provider.Service::getAlgorithm)
.collect(Collectors.toList());
答案 5 :(得分:0)
您可以使用以下代码找到JVM支持的确切列表:
java.lang.System.out.println(java.security.Security.getAlgorithms("MessageDigest"));
如果您有最新的JRE / JDK,则应该有可用的JavaScript,因此您可以启动“ jjs”(它应与java / javac / ...位于同一目录中)并在提示符下键入以上命令。显然,如果您在JVM中安装了特殊的提供程序(例如Bouncy Castle),则在启动“ jjs”时需要进行相应的配置。