使用 Java 的通用访问卡 (CAC) 身份验证
我基本上是在寻找一个地方来开始学习如何使用 java 与政府 CAC 卡交互。
最终,我的目标是了解如何使用 CAC 卡身份验证(通过 PIN 码)来授权访问使用 Tomcat/J2EE 服务器托管的网站。
但我需要从某个地方开始。 所以我想我首先要编写一个小的java程序来简单地从插入我键盘上的读卡器的CAC卡中读取CAC卡信息(DELL键盘,数字键盘上方有CAC读卡器)。
通过搜索google,我找到了cacard java项目(https://cacard.dev。 java.net/),已被 OpenSSO 项目取代。 但我似乎找不到如何使用它连接到卡、从卡读取数据等的示例代码。
有谁知道我在哪里可以找到一些示例代码,以便我可以开始学习如何与 CAC 交互使用java的卡?
谢谢
编辑:
经过更多研究后,我在想,我是否可以在 server.xml
文件的连接器元素中设置 clientAuth="true"
?
http://tomcat.apache.org/tomcat-6.0-doc/ssl -howto.html
clientAuth:如果您希望 Tomcat 要求所有 SSL 客户端提供客户端证书才能使用此套接字,请将此值设置为 true。
I'm bascially looking for someplace to start learning how to interface with a government CAC card using java.
Ultimately, my goal is to find out how to use CAC card authentication (by PIN number) to authorize access to a website hosted using a Tomcat/J2EE server.
But I'll need somewhere to start. So I figure I'd start by writing a small java program to simply read the CAC card information from the CAC card which is inserted into a card reader on my keyboard (DELL keyboard with CAC reader above the numeric keypad).
By searching google, I found the cacard java project (https://cacard.dev.java.net/) which was replaced by the OpenSSO project. But I can't seem to find sample code of how to use it to connect to a card, read from a card, etc.
Does anyone know where I can find some sample code so that I can start learning how to interact with a CAC card using java?
Thanks
EDIT:
After researching more, I was thinking, would I be able to just set clientAuth="true"
in the connector element in the server.xml
file?
http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html
clientAuth: Set this value to true if you want Tomcat to require all SSL clients to present a client Certificate in order to use this socket.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(3)
您需要创建一个名为 card.config
的文件,并在其中包含以下几行:
name = myConfig
library = /path/to/library/that/implements/cac/card/reader
然后尝试执行此操作:
import java.io.*;
import java.util.*;
import java.security.cert.CertificateException;
import java.security.KeyStoreException;
import java.security.cert.X509Certificate;
import java.security.KeyStore;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
public class Test
{
public static void main(String arg[]) throws Exception
{
try
{
//Create our certificates from our CAC Card
String configName = "card.config";
Provider p = new sun.security.pkcs11.SunPKCS11(configName);
Security.addProvider(p);
//Get the pin from user entered data
Console c = System.console();
char[] pin = c.readPassword("Enter your PIN: ");
KeyStore cac = null;
cac = KeyStore.getInstance("PKCS11");
cac.load(null, pin);
showInfoAboutCAC(cac);
}
catch(Exception ex)
{
//System.out.println("*" + ex.getMessage());
ex.printStackTrace();
System.exit(0);
}
}
public static void showInfoAboutCAC(KeyStore ks) throws KeyStoreException, CertificateException
{
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements())
{
String alias = aliases.nextElement();
X509Certificate[] cchain = (X509Certificate[]) ks.getCertificateChain(alias);
System.out.println("Certificate Chain for : " + alias);
for (int i = 0; i < cchain.length; i ++)
{
System.out.println(i + " SubjectDN: " + cchain[i].getSubjectDN());
System.out.println(i + " IssuerDN: " + cchain[i].getIssuerDN());
}
}
}
}
此时,您拥有一个密钥库,可用于创建 ssl 套接字以与https 网络服务器。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您是在创建 Web 应用程序,还是尝试编写在客户端运行的软件(有点像您自己的 Web 浏览器)?
如果您正在创建一个 Web 应用程序,那么它几乎只是标准的客户端认证身份验证。 证书来自硬件令牌这一事实对于服务器来说并没有太大改变; 如果您只想接受 CAC 证书,您可以在服务器验证客户端证书时指定一组可接受的证书策略。 (策略验证是 PKIX 验证的标准部分。)如果此应用程序面向政府客户,您需要与他们的安全团队密切合作,以确保您的解决方案满足他们的要求,这些要求可能很严格。 如果这是您的情况,请告诉我,我将用我们遇到的一些问题更新我的答案。
如果您正在编写客户端,并且需要访问物理阅读器,则可以使用 Sun PKCS #11 提供程序,自 Java 1.5 起。 我已经尝试过这个提供程序,您可以在 另一个答案。
在服务器上,您应该检查证书是否未被吊销。 然而,其中一些 CRL 非常庞大,我们有超过 100 Mb 的 CRL 文件,而内置的 Sun 吊销检查程序无法很好地扩展到这种大小。
您还需要确保 Tomcat 的“信任”密钥存储中拥有正确的根 CA 证书(政府根 CA 证书不太难找到,因为他们希望确保用户正确验证它们)。 我们还发现,除非用户手动将中间证书导入浏览器,否则 Firefox 不会发送整个证书链。
Are you creating the web application, or trying to write software that runs at the client (sort of like your own web browser)?
If you are creating a web application, it's pretty much just standard client certification authentication. The fact that the certificate came from a hardware token doesn't change much for the server; if you want to accept only CAC certificates, you can specify set of acceptable certificate policies when the server validates the client certificate. (Policy validation is a standard part of PKIX validation.) If this application is for a government customer, you'll need to work closely with their security team to ensure that your solution meets their requirements, which can be stringent. If this is your scenario, let me know and I'll update my answer with some of the issues that we encountered.
If you are writing a client, and need to access the physical reader, you may be able to use the Sun PKCS #11 provider, since Java 1.5. I've experimented with this provider, and you can read more about it in another answer.
On the server, you should check that the certificate is not revoked. However, some of these CRLs are enormous—we had over 100 Mb worth of CRL files, and the built-in Sun revocation checker does not scale well to this size.
You will also need to make sure that you have the right root CA certificates in Tomcat's "trust" key store (the government root CA certs are little harder to find because they want to make sure users are verifying them properly). We also found that Firefox does not send the entire certificate chain unless users import the intermediate certificates into their browser manually.