如何将多个信任库路径添加到"java.net.ssl.trustStore"?

Don*_*ild 12 java ssl certificate

我希望我的Java代码在一个密钥库中搜索服务器的CA证书...如果它无法找到特定的证书(我认为只有当我尝试通过LDAP连接到Directory Server时才会知道),它应该是在另一个密钥库中查找证书,我知道它的路径.

我试过这个:

System.setProperty("javax.net.ssl.trustStore", System.getProperty("java.home") + "/lib/security/cacerts" + System.getProperty("path.separator") + path/to/second/keystore);

但它似乎没有用.

只添加一个路径(其中任何一个)都可以工作,即如果找到证书则会像魅力一样运行,否则就会失败.

所以我的问题是:

  1. 是否有方法将多堆密钥库路径添加到javax.net.ssl.trustStore?

  2. 如果不可能我应该如何编写我的代码(我要求算法),以便它在第一次搜索后不会抛出异常而失败?

PS:我对Java不太熟悉.

以下是我的代码的相关部分:

if(useSSL)
{
  try 
  {   
    SSLContext se = SSLContext.getInstance("TLS");
    Security.addProvider(se.getProvider());
  }   
  catch(NoSuchAlgorithmException e) { }

  System.setProperty("javax.net.ssl.trustStore", System.getProperty("java.home") + "/lib/security/cacerts");

  com.org.ldap.LDAPSocketFactory ssf = new LDAPJSSESecureSocketFactory();
  LDAPConnection.setSocketFactory(ssf);
}

try 
{   
  lc = new LDAPConnection();
  lc.connect( ldapServer, ldapPort);
  lc.bind( ldapVersion,  ldapUser, (userInfo[1]).getBytes() );
}
catch (LDAPException le)
{
  le.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

Bru*_*uno 11

您不能拥有多条路径javax.net.ssl.trustStore.

最简单的方法是制作JRE的本地副本,并将cacerts证书从您的其他商店导入其中(有效地合并它们).(见keytool -importkeystore.)

否则,如果您事先知道所有LDAP连接将使用您的第二个密钥库(并且您还希望能够将默认信任库用于其他非相关连接),则可以SSLSocketFactory仅为此配置该信任存储.我不熟悉com.org.ldap.LDAPSocketFactory,但可能有选择这样做.(否则,您可以创建SSLContext使用第二个信任库初始化的自定义并获取SSLSocketFactory,如本答案中所述).

另一种更复杂的方法是创建一个自定义X509TrustManager包装默认信任管理器,捕获其异常并再次尝试使用您的第二个存储初始化的另一个信任管理器.这是可行的,但如果信任管理员都不接受您的证书,您需要确保它仍然会抛出异常(否则会出现安全漏洞).如果您不熟悉JSSE API(或Java),那么它可能不是最佳选择.

此外,System.setProperty("javax.net.ssl.trustStore", ...)在代码中使用时要小心:它是初始化默认值的读取内容SSLContext,但默认SSLContext值仅在第一次需要时初始化一次.之后设置此系统属性将不起作用(当然,除非其他库中的其他类也依赖于此值).


目前还不清楚你要用这个来实现什么,因为你总是会成功地添加一个已经存在的安全提供者:

  try 
  {   
    SSLContext se = SSLContext.getInstance("TLS");
    Security.addProvider(se.getProvider());
  }   
  catch(NoSuchAlgorithmException e) { }
Run Code Online (Sandbox Code Playgroud)