1. 概述
在这个教程中,我们将解释什么是信任锚。此外,我们将展示默认的信任存储(TrustStore)位置和预期的文件格式。最后,我们将澄清一个错误的原因:“java.security.InvalidAlgorithmParameterException
: trust anchors parameter must be non-empty”。
2. 信任锚定义
首先,我们来解释一下信任锚是什么。在加密系统中,信任锚定义了一个被假设并派生信任的基本实体。在X.509架构中,根证书就是一个信任锚。它还保证了链中所有其他证书的信任。
3. 信任存储的位置和格式
现在让我们来看看Java中的信任存储(TrustStore)的位置和格式。首先,Java会在两个位置查找信任存储(按顺序):
-
$JAVA_HOME/lib/security/jssecacerts
-
$JAVA_HOME/lib/security/cacerts
我们可以使用参数-Djavax.net.ssl.trustStore.
覆盖默认位置。另外,参数-Djavax.net.ssl.trustStorePassword
允许我们为信任存储提供密码。最终命令如下:
java -Djavax.net.ssl.trustStore=/some/loc/on/server/ our_truststore.jks -Djavax.net.ssl.trustStorePassword=our_password -jar application.jar
默认的信任存储格式是JKS。参数-Djavax.net.ssl.trustStoreType
允许覆盖默认的信任存储类型。
让我们看看在Java 16中执行keytool
实用程序对$JAVA_HOME/lib/security/cacerts
的输出:
$ keytool -list -cacerts
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 90 entries
....
如预期,密钥存储类型为JKS。此外,我们得到了文件中存储的90个证书。
4. 异常原因
现在我们来看一下“java.security.InvalidAlgorithmParameterException
: trustAnchors parameter must be non-empty”这个异常的原因。
首先,Java运行时仅在用于从密钥存储读取证书的PKIXParameters类中创建InvalidAlgorithmParameterException
。**PKIXParameters
类的构造函数会从给定的密钥存储中收集信任锚**。
当提供的密钥存储没有信任锚时,就会抛出这个异常:
...
if (trustAnchors.isEmpty()) {
throw new InvalidAlgorithmParameterException("the trustAnchors " +
"parameter must be non-empty");
}
...
让我们尝试重现这种情况。首先,我们创建一个空的密钥存储:
private KeyStore getKeyStore() throws CertificateException, NoSuchAlgorithmException, IOException, KeyStoreException {
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, "changeIt".toCharArray());
return ks;
}
现在,我们测试PKIXParameters
类的实例化:
@Test
public void whenOpeningTrustStore_thenExceptionIsThrown() throws Exception {
KeyStore keyStore = getKeyStore();
InvalidAlgorithmParameterException invalidAlgorithmParameterException =
Assertions.assertThrows(InvalidAlgorithmParameterException.class, () -> new PKIXParameters(keyStore));
Assertions.assertEquals("the trustAnchors parameter must be non-empty", invalidAlgorithmParameterException.getMessage());
}
正如预期的那样,构造函数抛出了异常。换句话说,当给定的密钥存储中没有可信证书时,无法创建PKIXParameters
类的实例。
5. 总结
在这篇简短的文章中,我们描述了什么是信任锚,展示了默认的信任存储位置和文件格式,并解释了“信任锚参数必须非空”错误的原因。
如往常一样,示例代码可在GitHub上找到此处。