SunMSCAPI无法识别某些密钥库条目的私钥

时间:2016-06-08 15:30:20

标签: java security authentication ssl mscapi

我很抱歉这太久了。如果您熟悉在Java中使用client-auth,您可以浏览/跳到底部。我花了很长时间才找到来自不同来源的所有相关信息。也许这会帮助别人。

我正在开发一个概念验证,以便使用Windows密钥库从Java客户端获取客户端身份验证。我有一个我可以请求或需要客户端证书的servlet。它只返回一个HTML响应,其中包含证书信息,包括主题DN和序列号。我已经通过浏览器(主要是Chrome和IE)进行了大量实验来验证它是否正常工作。我已成功完成客户端身份验证,使用我使用SSL生成的证书,并使用我公司内部CA颁发的证书。

我的下一步是让Java客户端与Java中的MSCAPI密钥库一起使用。我选择这条路线的原因是我们要使用的证书是由我们的内部CA颁发的,并自动添加到Windows中的个人密钥库中,并标记为不可导出。我知道,如果您是工作站的管理员,有一些方法可以使用一些免费工具将私钥从密钥库中取出。出于各种原因,在这种情况下这不是可行的选择。这是我最终得到的代码:

private static SSLSocketFactory getFactory() throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException 
{
  KeyStore roots = KeyStore.getInstance("Windows-ROOT", new SunMSCAPI());
  KeyStore personal = KeyStore.getInstance("Windows-MY", new SunMSCAPI());

  roots.load(null,null);
  personal.load(null,null);

  TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
  tmf.init(roots);

  KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
  kmf.init(personal, "".toCharArray());

  SSLContext context = SSLContext.getInstance("TLS");

  context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

  return context.getSocketFactory();
}

这有效,但是当我连接时,Java客户端使用我之前生成的客户端证书进行身份验证。我没有看到强行选择特定密钥的明显方法,因此我认为它只是选择了主机信任的第一个密钥。然后我删除了我从windows密钥库创建的这些证书,它将不再进行身份验证。我三重检查了服务器端是否仍然可以与浏览器一起使用。然后,我将这些证书读入个人密钥库,并从服务器端删除了我的伪CA的信任。仍然可以在浏览器中使用,而不是在客户端。

我添加了-Djavax.net.debug = ssl:握手到我的VM参数并开始查看输出。我看到的一件事是为“我已经添加的每个证书都找到了”找到关键字:[别名]“,而不是通过certmgr.msc的”自我注册“功能添加的证书。最初我认为这是因为它们是可导出的,但我删除它们并添加一个作为不可导出的并且java仍然可以使用它。我不知道为什么SunMSCAPI不会使用这些证书。我和内部CA创建的都是sha256RSA。两者都启用了客户端身份验证。当我添加以下代码时,我发现对于我想要使用的所有密钥对,isKeyEntry()为false:

Enumeration<String> aliases = personal.aliases();

while (aliases.hasMoreElements())
{
  String alias = aliases.nextElement();

  System.out.println(alias + " " + personal.isKeyEntry(alias));
}

我发现其他人有类似问题here,但没有明确答案。

0 个答案:

没有答案