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