简体   繁体   English

使用Java PKCS#11读取DoD公共访问卡

[英]Using Java PKCS#11 to read DoD Common Access Card

I have researched on how to use Sun PKCS#11 api to access a DoD CAC and possibly use the CAC to access (read-only) Active Directory. 我研究过如何使用Sun PKCS#11 api访问DoD CAC,并可能使用CAC访问(只读)Active Directory。 My problem has been, what I have found in most cases will make a reference to some code, but never shows the referenced code. 我的问题是,我在大多数情况下发现的将引用一些代码,但从不显示引用的代码。 I have found the following code, but gives an error. 我找到了以下代码,但是给出了错误。 Does anyone know of any code examples or clear documentation for using PKCS11 for CACs? 有没有人知道任何代码示例或使用PKCS11进行CAC的明确文档? Or an API solution which might work? 或者可能有效的API解决方案?

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.Security;


public class SmartCard {
    public static void main(String[] args) throws Exception {
        try {
            String configName = "pkcs11.properties";
            Provider p = new sun.security.pkcs11.SunPKCS11(configName);
            Security.addProvider(p);
            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) {
            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(" -SubjectDN: " + cchain[i].getSubjectDN());
                System.out.println(" -IssuerDN: " + cchain[i].getIssuerDN());
            }
        }
    }
}

java.security.ProviderException: Initialization failed
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:374)
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:103)
        at smartcard.SmartCard.main(SmartCard.java:21)
Caused by: java.io.IOException: The specified procedure could not be found.

        at sun.security.pkcs11.wrapper.PKCS11.connect(Native Method)
        at sun.security.pkcs11.wrapper.PKCS11.<init>(PKCS11.java:137)
        at sun.security.pkcs11.wrapper.PKCS11.getInstance(PKCS11.java:150)
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:312)
        ... 2 more

In the following code, configName is supposed to be a file path to some configuration file. 在以下代码中, configName应该是某个配置文件的文件路径。 It does not exist, or java is unable to read it, so an IOException is being thrown. 它不存在,或者java无法读取它,因此抛出了IOException Figure out what the file is supposed to be and create it, or otherwise ensure java has access to the file, and the code will run. 弄清楚该文件应该是什么并创建它,或者确保java有权访问该文件,并且代码将运行。

String configName = "pkcs11.properties";
Provider p = new sun.security.pkcs11.SunPKCS11(configName);

Reading the manual may help: http://docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.html#Config 阅读手册可能有所帮助: http//docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.html#Config

The properties file does exist, and is in the same directory as the application. 属性文件确实存在,并且与应用程序位于同一目录中。 And as far as I can tell, Java has access to the file. 据我所知,Java可以访问该文件。

If it helps, here's the contents of the file: 如果有帮助,这里是文件的内容:

name=SmartCard
library=C:/Program Files/Java/jre7/bin/j2pkcs11.dll

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM