CryptGetProvParam PP_ENUMCONTAINERS показывает мне только сертификат по умолчанию на смарт-карте

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

Когда я бегу

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

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

Базовый криптопровайдер смарт-карт Microsoft:
7c168bc3-dc1d-a627-c218-cd45729b42cb [Контейнер по умолчанию] AT_KEYEXCHANGE

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

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

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

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#?


person SeeR    schedule 26.06.2009    source источник


Ответы (1)


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

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

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

На самом деле это похоже на распространение ошибки в образце кода из «Расширение криптографии .NET с помощью 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;.

person woj    schedule 08.01.2010