使用 CNG 的加密配置功能

CNG API 提供了用于枚举和获取有关已注册提供程序的信息的函数。

枚举提供程序

使用 BCryptEnumRegisteredProviders 函数可枚举已注册的提供程序。 可以通过以下两种方式之一调用 BCryptEnumRegisteredProviders 函数:

  1. 第一种是让 BCryptEnumRegisteredProviders 函数分配内存。 这是通过传递 ppBuffer 参数的 NULL 指针的地址来完成的。 此代码将分配 Dm-crypt _ 提供程序 结构和关联字符串所需的内存。 以这种方式使用 BCryptEnumRegisteredProviders 函数时,必须通过将 PpBuffer 传递到 BCryptFreeBuffer 函数来释放不再需要的内存。

    下面的示例演示如何使用 BCryptEnumRegisteredProviders 函数为你分配缓冲区。

    #include <windows.h>
    
    #ifndef NT_SUCCESS
    #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
    #endif
    
    void EnumProviders1()
    {
        NTSTATUS status;
        ULONG cbBuffer = 0;
        PCRYPT_PROVIDERS pBuffer = NULL;
    
        /*
        Get the providers, letting the BCryptEnumRegisteredProviders 
        function allocate the memory.
        */
        status = BCryptEnumRegisteredProviders(&cbBuffer, &pBuffer);
    
        if (NT_SUCCESS(status))
        {
            if (pBuffer != NULL)
            {
                // Enumerate the providers.
                for (ULONG i = 0; i < pBuffer->cProviders; i++)
                {
                    printf("%S\n", pBuffer->rgpszProviders[i]);
                }
            }
        }
        else
        {
            printf("BCryptEnumRegisteredProviders failed with error " 
                "code 0x%08x\n", status);
        }
    
        if (NULL != pBuffer)
        {
            /*
            Free the memory allocated by the 
            BCryptEnumRegisteredProviders function.
            */
            BCryptFreeBuffer(pBuffer);
        }
    }
    
    
  2. 第二种方法是自行分配所需的内存。 为此,可调用 BCryptEnumRegisteredProviders函数,并将 PpBuffer 参数的 值为 NULLBCryptEnumRegisteredProviders 函数将置于 pcbBuffer 参数所指向的值中, dm-crypt _ 提供程序结构和所有字符串的所需大小(以字节为单位)。 然后,分配所需的内存,并在对 BCryptEnumRegisteredProviders 函数的第二次调用中为 ppBuffer 参数传递此缓冲区指针的地址。

    下面的示例演示如何使用 BCryptEnumRegisteredProviders 函数来分配和使用自己的缓冲区。

    #include <windows.h>
    #include <stdio.h>
    
    #ifndef NT_SUCCESS
    #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
    #endif
    
    void EnumProviders2()
    {
        NTSTATUS status;
        ULONG cbBuffer = 0;
    
        // Get the required size of the buffer.
        status = BCryptEnumRegisteredProviders(&cbBuffer, NULL);
    
        if (STATUS_BUFFER_TOO_SMALL == status)
        {
            // Allocate the buffer.
            PCRYPT_PROVIDERS pBuffer = 
                (PCRYPT_PROVIDERS)LocalAlloc(LPTR, cbBuffer);
            if (NULL != pBuffer)
            {
                // Get the providers in the buffer that was allocated.
                status = BCryptEnumRegisteredProviders(
                    &cbBuffer, 
                    &pBuffer);
                if (NT_SUCCESS(status))
                {
                    for (ULONG i = 0; i < pBuffer->cProviders; i++)
                    {
                        // Enumerate the providers.
                        printf("%S\n", pBuffer->rgpszProviders[i]);
                    }
                }
    
                // Free the memory that was allocated.
                LocalFree(pBuffer);
            }
        }
    }
    
    

正在获取提供程序注册信息

BCryptQueryProviderRegistration函数用于获取有关提供程序的其他特定于注册的信息。 此函数采用你要为其获取信息的提供程序的名称,所需的提供程序模式 (内核模式、用户模式或这两种模式) ,以及要为其检索注册信息的提供程序接口的标识符。 例如,若要获取 "Microsoft 基元访问接口" 提供程序的密码接口的用户模式注册信息,你将进行类似于下面的调用。

BCryptQueryProviderRegistration(
    MS_PRIMITIVE_PROVIDER,
    CRYPT_UM,
    BCRYPT_CIPHER_INTERFACE,
    //...
    );

BCryptEnumRegisteredProviders 函数一样, BCryptQueryProviderRegistration 函数可以为您分配内存,也可以自己分配内存。 这两个函数的过程是相同的。