CryptGetProvParam PP_ENUMCONTAINERS показывает мне только сертификат по умолчанию на смарт-карте - PullRequest
1 голос
/ 26 июня 2009

У меня есть смарт-карта Gemalto.NET.
Я импортировал в него 2 сертификата с помощью инструментов Gemalto, которые используют sconnect (который, как я подозреваю, использует Crypto API, чтобы сделать это при использовании в IE).

Когда я бегу

certutil -key -csp "Microsoft Base Smart Card Crypto Provider"

У меня следующий результат

Microsoft Base Smart Card Crypto Поставщик:
7c168bc3-dc1d-A627-C218-cd45729b42cb [Контейнер по умолчанию] AT_KEYEXCHANGE

badd537a-a377-431b-cbc9-8699dbe15e0e AT_KEYEXCHANGE

LoadKeys вернул Ключ не существует. 0x8009000d (-2146893811) CertUtil: Команда успешно завершена.

Теперь я хочу найти эти ключи в моей программе на C #. Для этого я написал следующий метод, который должен вернуть все ключи на определенной смарт-карте.

static List<string> EnumerateContainers(string card)
{
    var list = new List<string>();
    var provider = IntPtr.Zero;
    if (!CryptAcquireContext(ref provider, @"\\.\" + card + @"\", "Microsoft Base Smart Card Crypto Provider", 1, CspProviderFlags.UseMachineKeyStore))
        Debug.WriteLine("no context for " + card);

    uint bufferSize = 4096;
    var container = new StringBuilder((int)bufferSize);
    uint flags = CRYPT_FIRST;
    while(CryptGetProvParam(provider, PP_ENUMCONTAINERS, container, ref bufferSize, flags))
    {
        list.Add(container.ToString());
        flags = 0;
    }
    return list;
}

Но мой метод находит только ключ 7c168bc3-dc1d-a627-c218-cd45729b42cb, который является ключом по умолчанию. Что я должен сделать, чтобы найти все ключи / контейнеры, хранящиеся на смарт-карте ??

и позже

Как удалить эти ключи и импортировать новый с помощью C #?

1 Ответ

1 голос
/ 08 января 2010

Я сталкивался с той же проблемой и видел похожие сообщения в Интернете, но, наконец, я нашел ответ ... проверив код ошибки!

Причина в том, что значение pcbData изменяется вызываемой реализацией (для отражения длины возвращаемых данных) и должно быть установлено в размер буфера перед каждым вызовом.

Проверка GetLastError после сбоя показывает ошибку 234, а это именно то!

На самом деле это похоже на распространение ошибки в образце кода из «Расширения .NET Cryptography с CAPICOM и P / Invoke» (http://msdn.microsoft.com/en-us/library/ms867087.aspx)

dwFlags=CRYPT_FIRST;  //required initalization
StringBuilder sb = new StringBuilder(BUFFSIZE);
while (Win32.CryptGetProvParam(hProv, enumflags, sb, ref pcbData, dwFlags)) 
{
    dwFlags=0;            //required to continue entire enumeration
    containernames.Add(sb.ToString());
}

там, где в цикле отсутствует pcbData = BUFFSIZE;.

...