Каков стандартный/современный способ использования аутентификации по карте CAC/PIV в веб-приложениях Java/Tomcat?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Каков стандартный/современный способ использования аутентификации по карте CAC/PIV в веб-приложениях Java/Tomcat?

Сообщение Anonymous »

(См. важные примечания к редактированию в конце.)
Мы уже несколько дней изучаем карты CAC/PIV для нашего веб-приложения, и нашли отличную информацию, но нам все еще не хватает ее для наших конкретных нужд. Мы используем Spring Boot, Java и сервер Tomcat 9/10. По сути, наш вопрос: Каков отраслевой стандарт для реализации аутентификации по карте CAC/PIV в веб-приложении Spring Boot Java на сервере Tomcat? (Большинство источников, которые мы нашли) им больше 10 лет, а остальным 5–9 лет, поэтому нам просто нужна актуальная информация по этой теме.)
Наше веб-приложение будет иметь 2 метода вход в систему:
  • Имя пользователя, пароль и ключ TOTP (у нас это работает)
  • Имя пользователя, пароль и Карта CAC/PIV
(Метод, необходимый для каждого пользователя, частично будет определяться в зависимости от его роли.)
У нас было несколько идей:
Идея №1: Конфигурация сервера
Мы нашли несколько других, которые предлагают использовать clientAuth= «true» на нашем сервере Tomcat или аналогичный. [1] [2] [3] Это было бы идеально, так как это самый простой способ реализовать это, но поскольку нам нужны 2 метода, упомянутых выше, мы не хотим, чтобы приложение всегда< /em> требуется значок.
Примечание: кажется, есть возможность указать clientAuth="want" что запросит сертификат пользователя, но не откажет пользователю, который не предъявит сертификат. Мне еще нужно узнать, как это работает. (Использовать «want» не рекомендуется, так как в некоторых случаях это может выдавать предупреждения.)
Еще одно замечание: использование clientAuth="true" или «want» может оказаться успешным для некоторых, но на самом деле оно не дает нам нужный нам метод. По сути, он будет запрашивать сертификат с момента загрузки сервера. Если установлено значение «true», сервер не разрешит доступ к приложению, если он не примет предоставленный сертификат или не доверяет ему. Если установлено значение «хочу», сервер будет искать сертификат, но если ни один из них не найден (или ни один из них не является доверенным), он не будет хранить их, а просто позволит пользователя к приложению как обычно. Однако после этого невозможно запросить сертификат (с использованием любых настроек сервера).
Чтобы обойти эту проблему, мы подумали, что можно было бы сделать что-то вроде приложения «шлюз», единственной целью которого является аутентификация по бейджу. (Может быть, что-то вроде этого веб-сайта max.gov [4] или других сайтов департаментов, ссылки на которые есть на этой странице. Эта реализация на max.gov — это именно то, что нам нужно: возможность чтения бейджей или какой-либо другой метод.)Нам удалось получить сертификат сервера, чтобы использовать его для тестирования этой идеи! Мы все настроили, и я разобрался с конфигурацией server.xml: Я все еще учусь, как заставить это работать с требованиями нашего приложения. (См. мой похожий вопрос [33] о том, как мы заставили работать часть этого процесса. Ссылка [3] отлично объяснила процесс/идею.)
Идея № 2: Открыть- Библиотеки исходного кода
Используйте библиотеку с открытым исходным кодом из GitHub. Мы нашли несколько источников, которые рекомендуют их:
  • OpenSC [5]: этот правительственный сайт [6] также ссылается на него. , но это похоже на какое-то веб-расширение но написано в основном на C.
  • web-smart-card [ 7]: мы не уверены, как его использовать.
  • PKCS#11: на него ссылаются некоторые другие [8] [9] [10] ] но кажется, что это для десктопных приложений - это правда? И некоторые сказали, что это может быть медленно? И ответ по ссылке №9 использует сервлеты, которые не используются в приложениях Spring Boot (насколько я могу судить).
  • javax .smartcardio: эта библиотека Smart Card IO [20] имеет несколько полезных функций, но есть два недостатка: 1) нет необходимости, чтобы все смарт-карты следовали одним и тем же командам/форматам APDU, и 2) у него возникают проблемы с правильной работой при развертывании веб-приложения на сервере, т. е. оно не может найти карту или устройство чтения.
Мы читали о некоторых использование Java-апплетов, но это были старые обсуждения. Кроме того, вам, возможно, придется поработать с подписью апплета, а апплеты считаются несколько небезопасными.
Идея №3: запрос сертификата
Расследование подробнее о реализации аутентификации карт CAC/PIV на Login.gov, я понял, что ответ, данный по ссылке [11], на самом деле касается того, как выполняется аутентификация карты: «Вам будет гораздо легче разобраться в этом и найти информацию, если вы забудете это пользователи используют смарт-карту или CAC, и просто начните с идеи, что вы собираетесь использовать клиентские сертификаты для аутентификации».
Это обсуждение [22] может дать некоторую дополнительную информацию .
По сути, я узнал, что вам необходимо иметь URL-адрес https для вашего веб-приложения, чтобы ваш сервер мог устанавливать соединение SSL/TLS - это единственный способ вы можете запросить сертификат пользователя. Если вы это получите, теоретически вам просто нужно будет запросить сертификат X509 пользователя, используя что-то например:

Код: Выделить всё

X509Certificate[] x509certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");

if (x509certs != null && x509certs.length > 0) {
X509Certificate x509cert = x509certs[0];
try {
x509cert.checkValidity();
} catch (Exception e) {
System.out.println("error checking cert or cert is not valid.");
}
} else {
System.out.println("certs list is null or empty.");
}
(Убедитесь, что вы изменили javax на jakarta, если вы используете Tomcat 10 или более позднюю версию.)
Дополнительно Для тех, кто создает приложение для государственного учреждения, вы можете связаться с командой Login.gov на их сайте [17]. Если у вас или вашего агентства есть адрес электронной почты .gov, вы сможете создать учетную запись разработчика и использовать их систему для аутентификации пользователя.
Идея № 4: Прямая карта Связь
Карты CAC, PIV и другие считаются смарт-картами. Компьютеры обмениваются данными со смарт-картами через APDU (блоки данных протокола приложений) [18]. Есть несколько библиотек с открытым исходным кодом, которые могут работать, и у Oracle тоже есть кое-что: Java Card [19], Smart Card IO [20]. API Java Card в основном предназначен для создания и изменения карт и обычно использует апплеты, что не является для нас хорошим выбором.
Используя ввод-вывод смарт-карты, я могу, по крайней мере, проверить, есть ли карта присутствует и прочитайте ATR карты:

Код: Выделить всё

try {
// get all terminals
TerminalFactory factory = TerminalFactory.getDefault();
List terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);

// get the first terminal
CardTerminal cdTerminal = terminals.get(0);

try {
if (cdTerminal.isCardPresent()) {
// establish a connection with the card
Card card = cdTerminal.connect("*"); // don't limit the type, just in case your card is different
System.out.println("card: " + card);

ATR atr = card.getATR();
System.out.println("ATR: " + atr.getBytes().toString());

card.disconnect(false);
} else {
System.out.println("No card inserted!");
}

} catch (CardException e) {
System.out.println("Failed to determine if card is present.");
}
} catch (CardException e1) {
System.out.println("Failed in smart card io.");
}
Я надеялся использовать метод sendControlCommand() [21] для получения сертификата, но сложно найти информацию о том, что означают эти два параметра и какие параметры доступны для них. (См. [24], [25], [26)].
Я изучаю это, но у кого-то есть репозиторий GitHub [27], который использует эту библиотеку, и я' пытаюсь узнать, как они ею пользуются.
У этой библиотеки есть несколько полезных функций, но, к сожалению, есть два недостатка:
  • Не существует требования, чтобы все смарт-карты следовали одним и тем же командам/форматам APDU.
  • Функции библиотеки имеют проблемы с правильной работой при развертывании веб-приложения на сервере, т. е. он не может найти ни карту, ни устройство чтения.
Идея №5: Sun PKCS#11
Это обсуждение [23] и другие, которых я видел, рекомендуют Sun PKCS#11 API, но, очевидно, он устарел. Существуют возможные альтернативы (Bouncy Castle и IAIK PKCS#11 [28]), но все они требуют дополнительной встроенной библиотеки PKCS#11.
Другие идеи:
Мне нравится обсуждение здесь [11], но оно более теоретическое, без каких-либо примеров кода. В любом случае, если кто-то еще ищет способ выполнить аутентификацию по бейджу, ответ дает лучшую основу для понимания того, как на самом деле работает аутентификация по бейджу!
Эти два вопроса поднимают несколько хороших вопросов [ 12] [13], но ответов на них нет.
Некоторые используют node.js или React, как [это 14], но у меня слышал, что использовать это в приложении Spring Boot не самое лучшее. Сейчас я изучаю его подробнее, чтобы понять, что можно использовать (особенно для проверки наличия карты).
Существует также Руководство для разработчиков [15] для кард-ридера, который используется конечными пользователями этого приложения, но я пока не нашел там ничего полезного.
Мы также подумали об использовании доступной библиотеки от Okta, поскольку теперь у них есть возможность использовать методы аутентификации с помощью PIV-карты [16]. Однако похоже, что Okta — это платная услуга, которая нам не подойдет.
Я нашел рекомендацию попробовать низкоуровневый API, такой как PC/SC [29], но для этого также требуются команды APDU (которые могут зависеть от карты).
Изменения
14-5-2024: Мы больше не собираемся использовать Spring Boot Framework, поскольку потребуется время для преобразования старого кода JDBC в новый способ с использованием bean-компонента jdbcTemplate. Мы также рассматриваем Tomcat 9 и 10 (для двух разных приложений, оба с одинаковыми требованиями для входа в систему).
30.05.2024
: У меня есть провел дополнительные исследования и нашел множество хороших идей, но пока ни одна из них не привела к полному успеху. Я добавил примечания выше.
13.06.2024: (Разные изменения выше.) Я нашел простой способ прочитать сертификаты из интеллектуальная карточка! К сожалению, некоторые части не работают у меня так, как описано в источниках: у меня нет всплывающего окна выбора сертификата. Меня вдохновили следующие вопросы SO: [30] и этот [31], поэтому обязательно ознакомьтесь с ними, если мой вопрос вообще оказался для вас полезным!
Я сделал следующее:

Код: Выделить всё

// there are various types and providers, but these were the ones that worked
KeyStore keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
// load local certificates (the certificates visible in your browser)
keyStore.load(null);
// get all the names of the available certificates
Enumeration aliases = keyStore.aliases();
Теперь я могу просмотреть перечисление, чтобы увидеть доступные сертификаты! Затем вы сможете получить доступ к каждому из них, например

Код: Выделить всё

String als;
Certificate cert;
while (aliases.hasMoreElements()) {
als = aliases.nextElement();
System.out.println("Alias: " + als);
cert = keyStore.getCertificate(als); // get the certificate
// check the certificate
certs = keyStore.getCertificateChain(als); // get the certificate chain
// check the certificate chain
}
Существует несколько методов класса Certificate, которые можно использовать для его проверки; например, cert.getPublicKey(), cert.getType() и cert.verify() (убедитесь, что вы используете открытый ключ эмитента для проверки [32]). Если есть экземпляр сертификата X509Certificate, доступно гораздо больше методов!
Даже несмотря на этот прогресс, я до сих пор не нашел способа проверить PIN-код карты; это дает мне только общедоступную информацию из сертификата на карте.
24.06.2024: я добавил несколько примечаний к идее №1< /strong>, который кажется лучшим вариантом!
Ссылки на ссылки: (Я буду обновлять этот вопрос по мере продолжения исследования. )

Подробнее здесь: https://stackoverflow.com/questions/783 ... java-tomca
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»