Using Java PKCS # 11 to Read a DoD Shared Card

I explored how to use the Sun PKCS # 11 api to access CAC DoD and possibly use CAC to access (read-only) Active Directory. My problem was that in most cases I found a link to some code, but it never shows the link code. I found the following code but gives an error. Does anyone know any code examples or clear documentation for using PKCS11 for CAC? Or an API solution that might work?

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 
+4
source share
2 answers

In the following configName code, configName must be a path to some configuration file. It does not exist, or java cannot read it, therefore an IOException is thrown. Find out what the file should be and create it, or else make sure that java has access to the file and the code will run.

 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

+2
source

The properties file exists and is in the same directory as the application. And as far as I can tell, Java has access to the file.

If this helps, here is the contents of the file:

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

Source: https://habr.com/ru/post/1480783/


All Articles