示例 C 程序:枚举 CSP 提供程序和提供程序类型
以下示例列出了计算机上可用的 CSP,并使用以下 CryptoAPI 函数:
此示例使用 函数 MyHandleError。 此示例中包含此函数的代码。 此函数和其他辅助函数的代码也列在常规用途函数下。
以下示例演示如何枚举 CSP 和提供程序类型。
//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "crypt32.lib")
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <wincrypt.h>
void MyHandleError(TCHAR* s);
void Wait(TCHAR* s);
int _tmain(int argc, _TCHAR* argv[])
{
// Declare and initialize variables.
HCRYPTPROV hProv;
LPTSTR pszName;
DWORD dwType;
DWORD cbName;
DWORD dwIndex = 0;
BYTE* ptr;
ALG_ID aiAlgid;
DWORD dwBits;
DWORD dwNameLen;
CHAR szName[100];
BYTE pbData[1024];
DWORD cbData = 1024;
DWORD dwIncrement = sizeof(DWORD);
DWORD dwFlags = CRYPT_FIRST;
DWORD dwParam = PP_CLIENT_HWND;
CHAR* pszAlgType = NULL;
BOOL fMore = TRUE;
LPTSTR pbProvName;
DWORD cbProvName;
//--------------------------------------------------------------
// Print header lines for provider types.
_tprintf(TEXT("Listing Available Provider Types.\n"));
_tprintf(TEXT("Provider type Provider Type Name\n"));
_tprintf(TEXT("_____________ ")
TEXT("_____________________________________\n"));
// Loop through enumerating provider types.
dwIndex = 0;
while(CryptEnumProviderTypes(
dwIndex,
NULL,
0,
&dwType,
NULL,
&cbName))
{
//-----------------------------------------------------------
// cbName is the length of the name of the next provider
// type.
// Allocate memory in a buffer to retrieve that name.
if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))
{
MyHandleError(TEXT("ERROR - LocalAlloc failed!"));
}
//-----------------------------------------------------------
// Get the provider type name.
if (CryptEnumProviderTypes(
dwIndex++,
NULL,
NULL,
&dwType,
pszName,
&cbName))
{
_tprintf (TEXT(" %4.0d %s\n"),
dwType,
pszName);
}
else
{
MyHandleError(TEXT("ERROR - CryptEnumProviders"));
}
LocalFree(pszName);
}
//--------------------------------------------------------------
// Print header lines for providers.
_tprintf(TEXT("\n\nListing Available Providers.\n"));
_tprintf(TEXT("Provider type Provider Name\n"));
_tprintf(TEXT("_____________ ")
TEXT("_____________________________________\n"));
//---------------------------------------------------------------
// Loop through enumerating providers.
dwIndex = 0;
while(CryptEnumProviders(
dwIndex,
NULL,
0,
&dwType,
NULL,
&cbName))
{
//-----------------------------------------------------------
// cbName is the length of the name of the next provider.
// Allocate memory in a buffer to retrieve that name.
if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))
{
MyHandleError(TEXT("ERROR - LocalAlloc failed!"));
}
//-----------------------------------------------------------
// Get the provider name.
if (CryptEnumProviders(
dwIndex++,
NULL,
0,
&dwType,
pszName,
&cbName))
{
_tprintf (TEXT(" %4.0d %s\n"),
dwType,
pszName);
}
else
{
MyHandleError(TEXT("ERROR - CryptEnumProviders"));
}
LocalFree(pszName);
} // End while loop.
//---------------------------------------------------------------
// Get the name of the default CSP specified for the
// PROV_RSA_FULL type for the computer.
//---------------------------------------------------------------
// Get the length of the RSA_FULL default provider name.
if (!(CryptGetDefaultProvider(
PROV_RSA_FULL,
NULL,
CRYPT_MACHINE_DEFAULT,
NULL,
&cbProvName)))
{
MyHandleError(TEXT("Error getting the length of the ")
TEXT("default provider name."));
}
//---------------------------------------------------------------
// Allocate local memory for the name of the default provider.
if (!(pbProvName = (LPTSTR)LocalAlloc(
LMEM_ZEROINIT,
cbProvName)))
{
MyHandleError(TEXT("Error during memory allocation ")
TEXT("for provider name."));
}
//---------------------------------------------------------------
// Get the name of the default PROV_RSA_FULL provider.
if (CryptGetDefaultProvider(
PROV_RSA_FULL,
NULL,
CRYPT_MACHINE_DEFAULT,
pbProvName,
&cbProvName))
{
_tprintf(TEXT("\nThe default provider name is \"%s\"\n"),
pbProvName);
}
else
{
MyHandleError(TEXT("Getting the provider name failed."));
}
LocalFree(pbProvName);
//-----------------------------------------------------
// Acquire a cryptographic context.
if(!CryptAcquireContext(
&hProv,
NULL,
NULL,
PROV_RSA_FULL,
NULL))
{
MyHandleError(TEXT("Error during CryptAcquireContext!"));
}
//------------------------------------------------------
// Enumerate the supported algorithms.
//------------------------------------------------------
// Print header for algorithm information table.
_tprintf(TEXT("\nEnumerating the supported ")
TEXT("algorithms\n\n"));
_tprintf(TEXT(" Algid Bits Type ")
TEXT("Name Algorithm\n"));
_tprintf(TEXT(" Length")
TEXT(" Name\n"));
_tprintf(TEXT(" _______________________________________")
TEXT("_________________\n"));
while(fMore)
{
//------------------------------------------------------
// Retrieve information about an algorithm.
if(CryptGetProvParam(
hProv,
PP_ENUMALGS,
pbData,
&cbData,
dwFlags))
{
//-------------------------------------------------------
// Extract algorithm information from the pbData buffer.
dwFlags = 0;
ptr = pbData;
aiAlgid = *(ALG_ID *)ptr;
ptr += sizeof(ALG_ID);
dwBits = *(DWORD *)ptr;
ptr += dwIncrement;
dwNameLen = *(DWORD *)ptr;
ptr += dwIncrement;
strncpy_s(szName, sizeof(szName), (char *) ptr, dwNameLen);
//-------------------------------------------------------
// Determine the algorithm type.
switch(GET_ALG_CLASS(aiAlgid))
{
case ALG_CLASS_DATA_ENCRYPT:
pszAlgType = "Encrypt ";
break;
case ALG_CLASS_HASH:
pszAlgType = "Hash ";
break;
case ALG_CLASS_KEY_EXCHANGE:
pszAlgType = "Exchange ";
break;
case ALG_CLASS_SIGNATURE:
pszAlgType = "Signature";
break;
default:
pszAlgType = "Unknown ";
break;
}
//--------------------------------------------------------
// Print information about the algorithm.
printf(" %8.8xh %-4d %s %-2d %s\n",
aiAlgid,
dwBits,
pszAlgType,
dwNameLen,
szName);
}
else
{
fMore = FALSE;
}
}
Wait(TEXT("\nPress Enter to continue."));
if(!(CryptReleaseContext(hProv, 0)))
{
MyHandleError(TEXT("Error during CryptReleaseContext."));
}
if(GetLastError() == ERROR_NO_MORE_ITEMS)
{
_tprintf(TEXT("\nThe program completed without error.\n"));
}
else
{
MyHandleError(TEXT("Error reading algorithm!"));
}
} // End main.
//-------------------------------------------------------------------
// This example uses the function MyHandleError, a simple error
// handling function, to print an error message and exit
// the program.
// For most applications, replace this function with one
// that does more extensive error reporting.
void MyHandleError(TCHAR *s)
{
_tprintf(TEXT("An error occurred in running the program.\n"));
_tprintf(TEXT("%s\n"),s);
_tprintf(TEXT("Error number %x\n."), GetLastError());
_tprintf(TEXT("Program terminating.\n"));
exit(1);
}
void Wait(TCHAR *s)
{
char x;
_tprintf(s);
x = getchar();
}