KJKHyperion сказал в своем ответе :
Я обнаружил «волшебную» последовательность вызовов для импорта открытого ключа RSA в формате PEM. Вот, пожалуйста:
- декодировать ключ в двоичный двоичный объект с помощью CryptStringToBinary ; pass CRYPT_STRING_BASE64HEADER в dwFlags
- декодировать двоичный двоичный ключ в CERT_PUBLIC_KEY_INFO с помощью CryptDecodeObjectEx ; передать X509_ASN_ENCODING в dwCertEncodingType и X509_PUBLIC_KEY_INFO в lpszStructType
- декодировать BLOB-объект PublicKey из CERT_PUBLIC_KEY_INFO в ключевой BLOB-объект RSA с помощью CryptDecodeObjectEx ; передать X509_ASN_ENCODING в dwCertEncodingType и RSA_CSP_PUBLICKEYBLOB в lpszStructType
- импорт ключевого объекта RSA с помощью CryptImportKey
Эта последовательность действительно помогла мне понять, что происходит, но она не работала для меня как есть. Второй звонок CryptDecodeObjectEx
дал мне ошибку:
Msgstr "встречено неверное значение тега ASN.1".
После многих попыток понять документацию Microsoft я наконец понял, что вывод первого декодера не может быть снова декодирован как ASN, и что он фактически готов к импорту. С этим пониманием я нашел ответ по следующей ссылке:
http://www.ms -news.net / f2748 / проблема импортирующего-открытый ключ-4052577.html
Ниже приведена моя собственная программа, которая импортирует открытый ключ из файла .pem в контекст CryptApi:
int main()
{
char pemPubKey[2048];
int readLen;
char derPubKey[2048];
size_t derPubKeyLen = 2048;
CERT_PUBLIC_KEY_INFO *publicKeyInfo;
int publicKeyInfoLen;
HANDLE hFile;
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
/*
* Read the public key cert from the file
*/
hFile = CreateFileA( "c:\\pub.pem", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if ( hFile == INVALID_HANDLE_VALUE )
{
fprintf( stderr, "Failed to open file. error: %d\n", GetLastError() );
}
if ( !ReadFile( hFile, pemPubKey, 2048, &readLen, NULL ) )
{
fprintf( stderr, "Failed to read file. error: %d\n", GetLastError() );
}
/*
* Convert from PEM format to DER format - removes header and footer and decodes from base64
*/
if ( !CryptStringToBinaryA( pemPubKey, 0, CRYPT_STRING_BASE64HEADER, derPubKey, &derPubKeyLen, NULL, NULL ) )
{
fprintf( stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError() );
}
/*
* Decode from DER format to CERT_PUBLIC_KEY_INFO
*/
if ( !CryptDecodeObjectEx( X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPubKey, derPubKeyLen,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen ) )
{
fprintf( stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError() );
return -1;
}
/*
* Acquire context
*/
if( !CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) )
{
{
printf( "CryptAcquireContext failed - err=0x%x.\n", GetLastError() );
return -1;
}
}
/*
* Import the public key using the context
*/
if ( !CryptImportPublicKeyInfo( hProv, X509_ASN_ENCODING, publicKeyInfo, &hKey ) )
{
fprintf( stderr, "CryptImportPublicKeyInfo failed. error: %d\n", GetLastError() );
return -1;
}
LocalFree( publicKeyInfo );
/*
* Now use hKey to encrypt whatever you need.
*/
return 0;
}