Аутентификация с помощью карты общего доступа (CAC) с использованием Java - PullRequest
27 голосов
/ 13 февраля 2009

Я в основном ищу место, где можно начать учиться взаимодействию с правительственной картой CAC с использованием Java.

В конечном счете, моя цель - выяснить, как использовать проверку подлинности с помощью карты CAC (по PIN-коду) для авторизации доступа к веб-сайту, размещенному на сервере Tomcat / J2EE. Но мне нужно где-то начать. Поэтому я решил начать с написания небольшой Java-программы, которая просто считывает информацию о карте CAC с карты CAC, вставленной в кард-ридер на моей клавиатуре (клавиатура DELL с устройством чтения CAC над цифровой клавиатурой).

Поиском в Google я нашел проект cacard java (https://cacard.dev.java.net/), который был заменен проектом OpenSSO . Но я не могу найти пример кода о том, как использовать его для подключения к карте, чтения с карты и т. д.

Кто-нибудь знает, где я могу найти пример кода, чтобы я мог начать изучать, как взаимодействовать с картой CAC с помощью Java?

Спасибо

EDIT:

После более подробного изучения я подумал, смогу ли я просто установить clientAuth="true" в элементе разъема в файле server.xml?

http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html

clientAuth: установите для этого значения значение true, если вы хотите, чтобы Tomcat требовал, чтобы все клиенты SSL представляли сертификат клиента для использования этого сокета.

Ответы [ 3 ]

15 голосов
/ 13 февраля 2009

Вы создаете веб-приложение или пытаетесь написать программное обеспечение, которое работает на клиенте (вроде вашего собственного веб-браузера)?

Если вы создаете веб-приложение, это в значительной степени просто стандартная проверка подлинности клиента. Тот факт, что сертификат получен из аппаратного токена, для сервера мало что меняет; если вы хотите принимать только сертификаты CAC, вы можете указать набор допустимых политик сертификатов, когда сервер проверяет сертификат клиента. (Проверка политики является стандартной частью проверки PKIX.) Если это приложение предназначено для государственных заказчиков, вам необходимо тесно сотрудничать с их командой безопасности, чтобы убедиться, что ваше решение соответствует их требованиям, которые могут быть строгими. Если это ваш сценарий, дайте мне знать, и я дополню свой ответ некоторыми проблемами, с которыми мы столкнулись.

Если вы пишете клиент и вам нужен доступ к физическому считывателю, вы можете использовать Sun PKCS # 11 провайдера , начиная с Java 1.5. Я экспериментировал с этим провайдером, и вы можете прочитать больше об этом в другом ответе.


На сервере вы должны убедиться, что сертификат не отозван. Однако некоторые из этих списков отзыва сертификатов огромны - у нас было более 100 Мбайт файлов CRL, и встроенная программа проверки отзыва Sun плохо масштабируется до этого размера.

Вам также необходимо убедиться, что у вас есть правильные сертификаты корневого ЦС в хранилище ключей доверия "Tomcat" (правительственные сертификаты корневого ЦС найти немного сложнее, потому что они хотят убедиться, что пользователи проверяют их правильно). Мы также обнаружили, что Firefox не отправляет всю цепочку сертификатов, если пользователи не импортируют промежуточные сертификаты в свой браузер вручную.

9 голосов
/ 27 октября 2009

Вам необходимо создать файл с именем 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.

0 голосов
/ 09 июля 2009

Изучите использование сертификата с использованием приложения типа SSO, такого как OpenSSO или JOSSO . Агент должен быть проще встраивать, и он уже реализовал большинство деталей. Если вам нужно сделать это самостоятельно, у них также есть много документации, связанной с необходимыми шагами, такими как: настройка цифровых сертификатов

...