CryptProtectMemory 函数 (dpapi.h)

CryptProtectMemory 函数对内存进行加密,以防止其他人查看进程中的敏感信息。 例如,使用 CryptProtectMemory 函数加密包含密码的内存。 加密密码可防止其他人在将进程分页到交换文件时查看密码。 否则,密码以 纯文本 形式显示,可由其他人查看。

语法

DPAPI_IMP BOOL CryptProtectMemory(
  [in, out] LPVOID pDataIn,
  [in]      DWORD  cbDataIn,
  [in]      DWORD  dwFlags
);

参数

[in, out] pDataIn

指向要加密的内存块的指针。 cbDataIn 参数指定将加密的字节数。 如果内存空间中包含的数据小于指定的字节数,则将加密预期块外部的数据。 如果它大于 cbDataIn 字节,则只会加密第一个 cbDataIn 字节。

[in] cbDataIn

要加密的 pData 参数指向的内存字节数。 字节数必须是 Wincrypt.h 中定义的 CRYPTPROTECTMEMORY_BLOCK_SIZE 常量的倍数。

[in] dwFlags

此参数可以是以下标志之一。 加密和解密内存时,必须指定相同的标志。

含义
CRYPTPROTECTMEMORY_SAME_PROCESS
在同一进程中加密和解密内存。 在不同进程中运行的应用程序将无法解密数据。
CRYPTPROTECTMEMORY_CROSS_PROCESS
在不同进程中加密和解密内存。 在不同进程中运行的应用程序将能够解密数据。
CRYPTPROTECTMEMORY_SAME_LOGON
使用相同的登录凭据在不同的进程中加密和解密内存。 在不同进程中运行的应用程序将能够解密数据。 但是,进程必须以加密数据的同一用户身份运行,并且必须在同一登录会话中运行。

返回值

如果该函数成功,则函数返回 TRUE

如果函数失败,则返回 FALSE。 有关扩展的错误信息,请调用 GetLastError

注解

使用 CryptProtectMemoryCryptUnprotectMemory 进行密码加密是不安全的,因为数据在加密之前以纯文本形式存在于内存中,并且调用方随时解密数据以供使用。

通常,使用 CryptProtectMemory 函数来加密在进程运行时要解密的敏感信息。 请勿使用此函数保存稍后要解密的数据;如果计算机重启,将无法解密数据。 若要将加密数据保存到文件以便稍后解密,请使用 CryptProtectData 函数。

调用 CryptUnprotectMemory 函数以解密使用 CryptProtectMemory 函数加密的内存。 使用完敏感信息后,请通过调用 SecureZeroMemory 函数将其从内存中清除。

如果使用 RPC 或 LRPC 将加密数据传递到另一个进程,请使用 CRYPTPROTECTMEMORY_CROSS_PROCESS 或 CRYPTPROTECTMEMORY_SAME_LOGON 标志。 接收进程必须指定相同的标志来解密数据。 此外,如果使用共享内存,请使用这些标志。

如果客户端使用 CRYPTPROTECTMEMORY_SAME_LOGON 标志,则服务器在解密内存之前必须模拟客户端 (RpcImpersonateClient) 。

示例

以下示例调用 CryptProtectMemory 函数来加密内存中的数据。

#include <windows.h>
#include <stdio.h>
#include <Wincrypt.h>

#define SSN_STR_LEN 12  // includes null

void main()
{
    HRESULT hr = S_OK;
    LPWSTR pSensitiveText = NULL;
    DWORD cbSensitiveText = 0;
    DWORD cbPlainText = SSN_STR_LEN*sizeof(WCHAR);
    DWORD dwMod = 0;

    //  Memory to encrypt must be a multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE.
    if (dwMod = cbPlainText % CRYPTPROTECTMEMORY_BLOCK_SIZE)
        cbSensitiveText = cbPlainText +
		(CRYPTPROTECTMEMORY_BLOCK_SIZE - dwMod);
    else
        cbSensitiveText = cbPlainText;

    pSensitiveText = (LPWSTR)LocalAlloc(LPTR, cbSensitiveText);
    if (NULL == pSensitiveText)
    {
        wprintf(L"Memory allocation failed.\n");
        return E_OUTOFMEMORY;
    }

    //  Place sensitive string to encrypt in pSensitiveText.

    if (!CryptProtectMemory(pSensitiveText, cbSensitiveText,
		CRYPTPROTECTMEMORY_SAME_PROCESS))
    {
        wprintf(L"CryptProtectMemory failed: %d\n", GetLastError());
        SecureZeroMemory(pSensitiveText, cbSensitiveText);
        LocalFree(pSensitiveText);
        pSensitiveText = NULL;
        return E_FAIL;
    }

    //  Call CryptUnprotectMemory to decrypt and use the memory.

    SecureZeroMemory(pSensitiveText, cbSensitiveText);
    LocalFree(pSensitiveText);
    pSensitiveText = NULL;

    return hr;
}

要求

要求
最低受支持的客户端 Windows Vista [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 dpapi.h
Library Crypt32.lib
DLL Crypt32.dll

另请参阅

CryptProtectData

CryptUnprotectMemory

RtlDecryptMemory

RtlEncryptMemory