Как программно экспортировать сертификат с токена в .cer?

Есть rutoken 32K для использования совместно с КриптоПро. Возникла задача экспортировать с него сертификат с открытым ключом в формат .cer  (нужен для проверки ЭЦП на дальнем компьютере), причём реализовать это нужно на голом CryptoAPI и C++ Builder. Подскажите пожалуйста, как такое проделать?

Re: Как программно экспортировать сертификат с токена в .cer?

Stanley пишет:

Есть rutoken 32K для использования совместно с КриптоПро. Возникла задача экспортировать с него сертификат с открытым ключом в формат .cer  (нужен для проверки ЭЦП на дальнем компьютере), причём реализовать это нужно на голом CryptoAPI и C++ Builder. Подскажите пожалуйста, как такое проделать?

С контейнерами, ключами и сертификатами КриптоПро можно работать только через API КриптоПро, которое является реализацией CryptoApi. Соответственно, при разработке рекомендуем воспользоваться документацией КриптоПро: http://cpdn.cryptopro.ru/
А экспортировать сам сертификат в принципе можно и через GUI КриптоПро CSP. Почему Вам не подходит такой вариант?

Re: Как программно экспортировать сертификат с токена в .cer?

Vladimir Ivanov пишет:

С контейнерами, ключами и сертификатами КриптоПро можно работать только через API КриптоПро, которое является реализацией CryptoApi. Соответственно, при разработке рекомендуем воспользоваться документацией КриптоПро: http://cpdn.cryptopro.ru/

Я где-то случайно находил пример экспорта сертификата, там была последовательность вызовов с параметрами, ориентированными именно на экспорт с Рутокена. Но тогда было не нужно, а теперь уже не найти.

Vladimir Ivanov пишет:

Почему Вам не подходит такой вариант?

Потому что нужно написать программу, работающую в стиле "вставь красную флэшку, нажми на кнопку и всё само сделается". Экспорт сертификатов страшно далёк от того, чем занимаются потенциальные пользователи, и их слишком много, чтобы учить их этим заниматься.

Re: Как программно экспортировать сертификат с токена в .cer?

Если выбросить все проверки возвращаемых значений, то порядок примерно такой:

HCRYPTPROV hProv = NULL;
CryptAcquireContext(&hProv, TEXT(”<имя контйенера>”),...,CRYPT_SILENT);

HCRYPTKEY hPrivateKey = NULL;
CryptGetUserKey( hProv, dwKeyPairUsage, &hPrivateKey);

DWORD dwCertLength = 0;
CryptGetKeyParam( hPrivate_Key,
                  KP_CERTIFICATE,
                  NULL,
                  dwCertLength,
                  0 );
                  
BYTE* pCertificateData = new BYTE[ dwCertLength ]();
CryptGetKeyParam( m_hPrivate_Key,
                  KP_CERTIFICATE,
                  pCertificateData,
                  &dwCertLength,
                  0 );

HANDLE hCerFile = CreateFile(...,GENERIC_WRITE,...);

DWORD dwBytesWritten = 0;
WriteFile(hCerFile, pCertificateData, dwCertLength, dwBytesWritten, NULL);

CloseHandle(hFile);
delete[] pCertificateData;