Как читать учетные данные со смарт-карты в c #

В моей организации пользователи должны использовать SmartCard для интерактивного входа на станции Windows (95, Vista и 7). почти ежедневно нам нужно читать учетные данные, хранящиеся на смарт-карте, и сравнивать их с ActiveDirectory, без реализации настраиваемого диспетчера учетных данных. Мы сравниваем следующие поля: userPrincialName и sAMAccountName.

Не могли бы вы показать мне код, демонстрирующий, как считывать учетные данные со смарт-карты, или направить меня к статье / коду в Интернете?

Поиск в Интернете предполагал реализацию диспетчера учетных данных или использование других языков (например, C, C ++). Также я наткнулся на эту статью: http://www.codeproject.com/Articles/17013/Smart-Card-Framework-for-NET, написанный orouit, который представляет собой основу для работы со смарт-картами, но я думаю, что это слишком много для моей простой задачи. Что вы думаете?


person Hamed Salameh    schedule 03.08.2012    source источник
comment
Я бы посоветовался с производителем устройства чтения смарт-карт, вам нужно будет узнать, как работает API его драйвера.   -  person Alex    schedule 03.08.2012
comment
Работа со смарт-картами может показаться простой задачей, но внешний вид может быть обманчивым. Как сказал Алекс, вам, возможно, придется использовать API вашего устройства чтения смарт-карт, но, скорее всего, стандартный Windows API должен помочь. Статью, которую вы нашли, необходимо прочитать, и подход, к сожалению, не лишний.   -  person dandan78    schedule 03.08.2012
comment
Алекс - К сожалению, на сайте производителя читателя (местного производителя) нет документации или API. Спасибо dandan78, Если статью обязательно к прочтению, то я сделаю это и прочитаю. Хорошего дня.   -  person Hamed Salameh    schedule 03.08.2012
comment
Согласен, это непростая задача вообще. Windows API постоянно меняется, и создание или добавление к процессу входа в систему может привести к месяцам удовольствия. Если вы не знаете, как это сделать, вам гораздо лучше купить его у продавца карт, который уже реализовал это.   -  person Maarten Bodewes    schedule 06.08.2012
comment
Windows 95, теперь у вас должно быть kdding, не так ли? Правильно? Пожалуйста?   -  person Maarten Bodewes    schedule 06.08.2012


Ответы (1)


Что ж, если вы разрабатываете под Windows, после того, как вы вставите смарт-карту, окна извлекут все сертификаты со смарт-карты и поместят их в хранилище моих сертификатов.

var smartCardCerts = new List<X509Certificate2>();
var myStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
myStore.Open(OpenFlags.ReadOnly);
foreach(X509Certificate2 cert in myStore.Certificates)
{
  if( !cert.HasPrivateKey ) continue; // not smartcard for sure
  var rsa = cert.PrivateKey as RSACryptoServiceProvider;
  if( rsa==null ) continue; // not smart card cert again
  if( rsa.CspKeyContainerInfo.HardwareDevice ) // sure - smartcard
  {
     // inspect rsa.CspKeyContainerInfo.KeyContainerName Property
     // or rsa.CspKeyContainerInfo.ProviderName (your smartcard provider, such as 
     // "Schlumberger Cryptographic Service Provider" for Schlumberger Cryptoflex 4K
     // card, etc
     var name = cert.Name;
     rsa.SignData(); // to confirm presence of private key - to finally authenticate
  }
}

в настоящее время через .NET доступно множество криптографических API. Но вы также можете использовать API напрямую Crypto API

например, вы можете получить доступ к смарт-карте напрямую через

CryptAcquireContext(&hProv,"\\.\<Reader Name>\<Container Name>",...)

где имя устройства чтения - это имя устройства чтения карт, а имя контейнера - это имя rsa.KeyContainerName в приведенном выше фрагменте кода. Есть несколько способов доступа к подобной информации, и Crypto API не очень единообразный или простой. в качестве подсказки .NET-версией CryptAcquireContext является RSACryptoServiceProvider с CspParameters, где при необходимости вы можете указать имя контейнера.

Хорошо найти пользователя в ActiveDirectory можно с помощью System.DirectoryServices.DirectoyEntry и System.DirectoryServices.DirectorySearcher, но не забывайте System.DirectoryServices.ActiveDirectory.Forest и связанный API, который упрощает понимание некоторых вещей.

Вы могли бы получить

person aiodintsov    schedule 07.09.2012
comment
Мне пришлось внести в это коррективы, чтобы заставить его работать. Вы должны открыть хранилище сертификатов с помощью myStore.Open(OpenFlags.ReadOnly), прежде чем сможете получить из него какие-либо сертификаты. Во-вторых, вы не можете пройти через myStore вместо этого вы хотите пройти через myStore.Certificates. - person mpursuit; 16.07.2015