如何使用Java从Windows上的智能卡(MSCAPI)获取用户身份?

问题描述:

我想通过Sun的MSCAPIProvider从Windows上的Java胖客户端的智能卡(PKI)获取用户身份。我们的目标是:如何使用Java从Windows上的智能卡(MSCAPI)获取用户身份?

  1. 用户打开应用程序
  2. 提示卡
  3. 提示输入PIN
  4. 我得到的X509Certicate在Java中
  5. 授予访问权限,等等

我已找到基于this *问题示例哪些列表的所有证书在我的商店,我可以签署一些字节与Microsoft智能卡提供商PIN提示。

这是我的代码:

Provider provider = Security.getProvider("SunMSCAPI"); 
KeyStore store = KeyStore.getInstance("Windows-MY", provider); 
store.load(null, null); 

System.out.println(store); 
Enumeration<?> aliases = store.aliases(); 
while(aliases.hasMoreElements()) { 
    String alias = aliases.nextElement().toString(); 
    Certificate[] signerKey = (Certificate[]) store.getCertificateChain(alias); 
    Object entry = store.getKey(alias, null); 
    System.out.println(alias + " " + Arrays.toString(signerKey)); 
    System.out.println(entry); 
} 

Signature sig = Signature.getInstance("SHA1withRSA",provider); 
PrivateKey key = (PrivateKey) store.getKey("Michael-O", null); 

sig.initSign(key); 
sig.update("Test".getBytes()); 
System.out.println(Arrays.toString(sig.sign())); 

现在我面临两个问题:

  1. 我不知道他的别名可能是什么(鸡蛋的问题)
  2. 怎么办我强制使用X509Cert进行PIN授权,并通过HTTPS建立SSL上下文?

哪些是缺失的位?

+0

您是否试图通过请求存储中的所有密钥来过滤掉别名?您是否尝试添加[CallbackHandler](http://docs.oracle.com/javase/7/docs/api/javax/security/auth/callback/CallbackHandler.html)? – 2013-03-06 00:29:16

+0

1.'PrivateKey entry =(PrivateKey)store.getKey(alias,null);'在一个循环中。用卡片钥匙不打印。当我放入卡时,钥匙被列出。下次运行时卸下卡让我问。在任何时候我都被要求输入我的个人识别码。 2. CallbackHandler如何帮助我,1.不知道别名,2.想使用MS智能卡提供程序而不是自定义对话框? – 2013-03-06 08:40:18

+0

您可以使用'aliases()'和'isKeyEntry()'从KeyStore请求所有密钥别名,也许这将有助于检索密钥?至于CallbackHandler,如果您获得PIN提示可能取决于智能卡附带的软件的实施。我没有看到任何需要使用提供者的密钥提示的要求(并且我个人不希望在应用程序之外提供PIN提示 - 我想知道我使用的密钥是什么,但这是个人偏好)。 – 2013-03-07 19:58:33

对于Windows的情况,通常智能卡供应商提供两个驱动程序。

  • 之一来访问和使用所述PKCS11协议智能卡登入。
  • 其他一个访问和使用Windows加密服务提供商签署(又名CSP

当您使用SunMSCAPI提供商可以访问本地用户窗口密钥库,如果没有安装一些CSP智能卡驱动程序在上面;你也可以通过它看到智能卡证书(但是你不知道本地和智能卡之间的区别,因为Windows密钥库充当接口)。

如果您尝试访问智能卡的公开证书,但是sunMSCAPI您正在访问公钥,因此不需要引入PIN。但是,如果您尝试执行签名,那么Windows密钥库将操作委托给智能卡CSP,这将提示您输入密码

现在要回答你的两个具体问题:

  1. 我不知道他的别名可能是(鸡蛋的问题)

一种选择可能是在弹出窗口中打印所有证书(例如主题或序列号)的信息(保持别名和您显示的描述之间的关系),让用户选择要使用的证书,然后在内部可以使用别名来引用所选 证书;这就像任何https验证在需要客户端验证时一样工作;浏览器向您显示可能的证书以进行身份​​验证。

https你可以做一些过滤器中的服务器,只显示与某些条件匹配哪些证书(例如,你可以过滤一些标准证书Apache的;对于发行的特定CA的例子证明),但最终用户必须选择所需的一个来执行验证。

你也可以做一些类似的过滤器,例如从keystore获取证书属性或证书链,只显示你认为适合哪些请求者......但最后如果在你过滤后有多个已经让用户决定选择哪一个。

  1. 如何强制PIN授权与X509Cert与 虽然建立一个HTTPS的SSL上下文的结果?
  2. 如果通过sunMSCAPI供应商我认为你可以不关心PIN委托私钥访问操作的智能卡CSP,让CSP照顾它适合你。

    如果由于某种原因,你需要保持PIN那么一个可能的选择是使用不同的供应商(SunPKCS11)直接实例化的智能卡(不通过CSP),并使用CallbackHandler(如@Maarten Bodewes建议在评论中)照顾它。然而,恕我直言,如果在这种情况下所有的客户端都在Windows上,我建议您像使用sunMSCAPI一样避免使用不同的智能卡驱动程序实现PKCS11问题。

开始=>