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
程式庫 Crypt32.lib
Dll Crypt32.dll

另請參閱

CryptProtectData

CryptUnprotectMemory

RtlDecryptMemory

RtlEncryptMemory