2020-03-09 11:54:19 -04:00
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
|
|
|
|
namespace Vanara.PInvoke
|
|
|
|
|
{
|
|
|
|
|
/// <summary>Methods and data types found in Crypt32.dll.</summary>
|
|
|
|
|
public static partial class Crypt32
|
|
|
|
|
{
|
|
|
|
|
/// <summary>Flags for CryptProtectData.</summary>
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "765a68fd-f105-49fc-a738-4a8129eb0770")]
|
|
|
|
|
[Flags]
|
|
|
|
|
public enum CryptProtectFlags
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// This flag is used for remote situations where presenting a user interface (UI) is not an option. When this flag is set and a
|
|
|
|
|
/// UI is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
|
|
|
|
|
/// ERROR_PASSWORD_RESTRICTION code.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CRYPTPROTECT_UI_FORBIDDEN = 0x1,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// When this flag is set, it associates the data encrypted with the current computer instead of with an individual user. Any
|
|
|
|
|
/// user on the computer on which CryptProtectData is called can use CryptUnprotectData to decrypt the data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CRYPTPROTECT_LOCAL_MACHINE = 0x4,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Force credential synchronize during CryptProtectData(). Synchronize is the only operation that occurs during this operation.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CRYPTPROTECT_CRED_SYNC = 0x8,
|
|
|
|
|
|
|
|
|
|
/// <summary>Generate an Audit on protect and unprotect operations.</summary>
|
|
|
|
|
CRYPTPROTECT_AUDIT = 0x10,
|
|
|
|
|
|
|
|
|
|
/// <summary>Protect data with a non-recoverable key.</summary>
|
|
|
|
|
CRYPTPROTECT_NO_RECOVERY = 0x20,
|
|
|
|
|
|
|
|
|
|
/// <summary>Verify the protection of a protected blob.</summary>
|
|
|
|
|
CRYPTPROTECT_VERIFY_PROTECTION = 0x40,
|
|
|
|
|
|
|
|
|
|
/// <summary>Regenerate the local machine protection.</summary>
|
|
|
|
|
CRYPTPROTECT_CRED_REGENERATE = 0x80
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Flags for CryptProtectMemory and CryptUnprotectMemory</summary>
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "6b372552-87d4-4047-afa5-0d1113348289")]
|
|
|
|
|
[Flags]
|
|
|
|
|
public enum CryptProtectMemoryFlags
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt
|
|
|
|
|
/// the data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CRYPTPROTECTMEMORY_SAME_PROCESS = 0x00,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CRYPTPROTECTMEMORY_CROSS_PROCESS = 0x01,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Use the same logon credentials to encrypt and decrypt memory in different processes. An application running in a different
|
|
|
|
|
/// process will be able to decrypt the data. However, the process must run as the same user that encrypted the data and in the
|
|
|
|
|
/// same logon session.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CRYPTPROTECTMEMORY_SAME_LOGON = 0x02,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Flags that indicate when prompts to the user are to be displayed.</summary>
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "412ce598-a7c9-446d-bd98-6583a20d6cd7")]
|
|
|
|
|
[Flags]
|
|
|
|
|
public enum CryptProtectPrompt : uint
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// This flag can be combined with CRYPTPROTECT_PROMPT_ON_PROTECT to enforce the UI (user interface) policy of the caller. When
|
|
|
|
|
/// CryptUnprotectData is called, the dwPromptFlags specified in the CryptProtectData call are enforced.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CRYPTPROTECT_PROMPT_ON_UNPROTECT = 0x1,
|
|
|
|
|
|
|
|
|
|
/// <summary>This flag is used to provide the prompt for the protect phase.</summary>
|
|
|
|
|
CRYPTPROTECT_PROMPT_ON_PROTECT = 0x2,
|
|
|
|
|
|
|
|
|
|
/// <summary>Reserved.</summary>
|
|
|
|
|
CRYPTPROTECT_PROMPT_RESERVED = 0x04,
|
|
|
|
|
|
|
|
|
|
/// <summary>Default to strong variant UI protection (user supplied password currently).</summary>
|
|
|
|
|
CRYPTPROTECT_PROMPT_STRONG = 0x08,
|
|
|
|
|
|
|
|
|
|
/// <summary>Require strong variant UI protection (user supplied password currently).</summary>
|
|
|
|
|
CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 0x10,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>CryptProtectData</c> function performs encryption on the data in a DATA_BLOB structure. Typically, only a user with the
|
|
|
|
|
/// same logon credential as the user who encrypted the data can decrypt the data. In addition, the encryption and decryption
|
|
|
|
|
/// usually must be done on the same computer. For information about exceptions, see Remarks.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pDataIn">A pointer to a DATA_BLOB structure that contains the plaintext to be encrypted.</param>
|
|
|
|
|
/// <param name="szDataDescr">
|
|
|
|
|
/// A string with a readable description of the data to be encrypted. This description string is included with the encrypted data.
|
|
|
|
|
/// This parameter is optional and can be set to <c>NULL</c>.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pOptionalEntropy">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used to encrypt the data. The
|
|
|
|
|
/// <c>DATA_BLOB</c> structure used in the encryption phase must also be used in the decryption phase. This parameter can be set to
|
|
|
|
|
/// <c>NULL</c> for no additional entropy. For information about protecting passwords, see Handling Passwords.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pvReserved">Reserved for future use and must be set to <c>NULL</c>.</param>
|
|
|
|
|
/// <param name="pPromptStruct">
|
|
|
|
|
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
|
|
|
|
|
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c> in both the encryption and decryption phases.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="dwFlags">
|
|
|
|
|
/// <para>This parameter can be one of the following flags.</para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Value</term>
|
|
|
|
|
/// <term>Meaning</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_LOCAL_MACHINE</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// When this flag is set, it associates the data encrypted with the current computer instead of with an individual user. Any user
|
|
|
|
|
/// on the computer on which CryptProtectData is called can use CryptUnprotectData to decrypt the data.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// This flag is used for remote situations where presenting a user interface (UI) is not an option. When this flag is set and a UI
|
|
|
|
|
/// is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
|
|
|
|
|
/// ERROR_PASSWORD_RESTRICTION code.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_AUDIT</term>
|
|
|
|
|
/// <term>This flag generates an audit on protect and unprotect operations.</term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pDataOut">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that receives the encrypted data. When you have finished using the <c>DATA_BLOB</c>
|
|
|
|
|
/// structure, free its <c>pbData</c> member by calling the LocalFree function.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
|
|
|
|
|
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Typically, only a user with logon credentials that match those of the user who encrypted the data can decrypt the data. In
|
|
|
|
|
/// addition, decryption usually can only be done on the computer where the data was encrypted. However, a user with a roaming
|
|
|
|
|
/// profile can decrypt the data from another computer on the network.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// If the CRYPTPROTECT_LOCAL_MACHINE flag is set when the data is encrypted, any user on the computer where the encryption was done
|
|
|
|
|
/// can decrypt the data.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The function creates a session key to perform the encryption. The session key is derived again when the data is to be decrypted.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The function also adds a Message Authentication Code (MAC) (keyed integrity check) to the encrypted data to guard against data tampering.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>To encrypt memory for temporary use in the same process or across processes, call the CryptProtectMemory function.</para>
|
|
|
|
|
/// <para>Examples</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The following example shows encryption of the data in a DATA_BLOB structure. The <c>CryptProtectData</c> function does the
|
|
|
|
|
/// encryption by using a session key that the function creates by using the user's logon credentials. For another example that uses
|
|
|
|
|
/// this function, see Example C Program: Using CryptProtectData.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata DPAPI_IMP BOOL CryptProtectData( DATA_BLOB
|
|
|
|
|
// *pDataIn, LPCWSTR szDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
|
|
|
|
|
// dwFlags, DATA_BLOB *pDataOut );
|
|
|
|
|
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "765a68fd-f105-49fc-a738-4a8129eb0770")]
|
|
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
|
|
|
public static extern bool CryptProtectData(in CRYPTOAPI_BLOB pDataIn, [Optional, MarshalAs(UnmanagedType.LPWStr)] string szDataDescr, in CRYPTOAPI_BLOB pOptionalEntropy,
|
|
|
|
|
[Optional] IntPtr pvReserved, in CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, CryptProtectFlags dwFlags, IntPtr pDataOut);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>CryptProtectData</c> function performs encryption on the data in a DATA_BLOB structure. Typically, only a user with the
|
|
|
|
|
/// same logon credential as the user who encrypted the data can decrypt the data. In addition, the encryption and decryption
|
|
|
|
|
/// usually must be done on the same computer. For information about exceptions, see Remarks.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pDataIn">A pointer to a DATA_BLOB structure that contains the plaintext to be encrypted.</param>
|
|
|
|
|
/// <param name="szDataDescr">
|
|
|
|
|
/// A string with a readable description of the data to be encrypted. This description string is included with the encrypted data.
|
|
|
|
|
/// This parameter is optional and can be set to <c>NULL</c>.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pOptionalEntropy">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used to encrypt the data. The
|
|
|
|
|
/// <c>DATA_BLOB</c> structure used in the encryption phase must also be used in the decryption phase. This parameter can be set to
|
|
|
|
|
/// <c>NULL</c> for no additional entropy. For information about protecting passwords, see Handling Passwords.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pvReserved">Reserved for future use and must be set to <c>NULL</c>.</param>
|
|
|
|
|
/// <param name="pPromptStruct">
|
|
|
|
|
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
|
|
|
|
|
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c> in both the encryption and decryption phases.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="dwFlags">
|
|
|
|
|
/// <para>This parameter can be one of the following flags.</para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Value</term>
|
|
|
|
|
/// <term>Meaning</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_LOCAL_MACHINE</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// When this flag is set, it associates the data encrypted with the current computer instead of with an individual user. Any user
|
|
|
|
|
/// on the computer on which CryptProtectData is called can use CryptUnprotectData to decrypt the data.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// This flag is used for remote situations where presenting a user interface (UI) is not an option. When this flag is set and a UI
|
|
|
|
|
/// is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
|
|
|
|
|
/// ERROR_PASSWORD_RESTRICTION code.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_AUDIT</term>
|
|
|
|
|
/// <term>This flag generates an audit on protect and unprotect operations.</term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pDataOut">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that receives the encrypted data. When you have finished using the <c>DATA_BLOB</c>
|
|
|
|
|
/// structure, free its <c>pbData</c> member by calling the LocalFree function.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
|
|
|
|
|
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Typically, only a user with logon credentials that match those of the user who encrypted the data can decrypt the data. In
|
|
|
|
|
/// addition, decryption usually can only be done on the computer where the data was encrypted. However, a user with a roaming
|
|
|
|
|
/// profile can decrypt the data from another computer on the network.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// If the CRYPTPROTECT_LOCAL_MACHINE flag is set when the data is encrypted, any user on the computer where the encryption was done
|
|
|
|
|
/// can decrypt the data.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The function creates a session key to perform the encryption. The session key is derived again when the data is to be decrypted.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The function also adds a Message Authentication Code (MAC) (keyed integrity check) to the encrypted data to guard against data tampering.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>To encrypt memory for temporary use in the same process or across processes, call the CryptProtectMemory function.</para>
|
|
|
|
|
/// <para>Examples</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The following example shows encryption of the data in a DATA_BLOB structure. The <c>CryptProtectData</c> function does the
|
|
|
|
|
/// encryption by using a session key that the function creates by using the user's logon credentials. For another example that uses
|
|
|
|
|
/// this function, see Example C Program: Using CryptProtectData.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata DPAPI_IMP BOOL CryptProtectData( DATA_BLOB
|
|
|
|
|
// *pDataIn, LPCWSTR szDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
|
|
|
|
|
// dwFlags, DATA_BLOB *pDataOut );
|
|
|
|
|
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "765a68fd-f105-49fc-a738-4a8129eb0770")]
|
|
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
|
|
|
public static extern bool CryptProtectData(in CRYPTOAPI_BLOB pDataIn, [Optional, MarshalAs(UnmanagedType.LPWStr)] string szDataDescr, [Optional] IntPtr pOptionalEntropy,
|
|
|
|
|
[Optional] IntPtr pvReserved, [Optional] IntPtr pPromptStruct, CryptProtectFlags dwFlags, IntPtr pDataOut);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>CryptProtectMemory</c> function encrypts memory to prevent others from viewing sensitive information in your process. For
|
|
|
|
|
/// example, use the <c>CryptProtectMemory</c> function to encrypt memory that contains a password. Encrypting the password prevents
|
|
|
|
|
/// others from viewing it when the process is paged out to the swap file. Otherwise, the password is in plaintext and viewable by others.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pDataIn">
|
|
|
|
|
/// A pointer to the block of memory to encrypt. The cbData parameter specifies the number of bytes that will be encrypted. If the
|
|
|
|
|
/// data contained in the memory space is smaller than the number of bytes specified, data outside of the intended block will be
|
|
|
|
|
/// encrypted. If it is larger than cbData bytes, then only the first cbData bytes will be encrypted.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="cbDataIn">
|
|
|
|
|
/// Number of bytes of memory pointed to by the pData parameter to encrypt. The number of bytes must be a multiple of the
|
|
|
|
|
/// <c>CRYPTPROTECTMEMORY_BLOCK_SIZE</c> constant defined in Wincrypt.h.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="dwFlags">
|
|
|
|
|
/// <para>This parameter can be one of the following flags. You must specify the same flag when encrypting and decrypting the memory.</para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Value</term>
|
|
|
|
|
/// <term>Meaning</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECTMEMORY_SAME_PROCESS</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt the data.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECTMEMORY_CROSS_PROCESS</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECTMEMORY_SAME_LOGON</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// Use the same logon credentials to encrypt and decrypt memory in different processes. An application running in a different
|
|
|
|
|
/// process will be able to decrypt the data. However, the process must run as the same user that encrypted the data and in the same
|
|
|
|
|
/// logon session.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
|
|
|
|
|
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Using CryptProtectMemory and CryptUnprotectMemory for password encryption is not secure because the data exists as plaintext in
|
|
|
|
|
/// memory before it is encrypted and at any time the caller decrypts it for use.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Typically, you use the <c>CryptProtectMemory</c> function to encrypt sensitive information that you are going to decrypt while
|
|
|
|
|
/// your process is running. Do not use this function to save data that you want to decrypt later; you will not be able to decrypt
|
|
|
|
|
/// the data if the computer is restarted. To save encrypted data to a file to decrypt later, use the CryptProtectData function.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Call the CryptUnprotectMemory function to decrypt memory encrypted with the <c>CryptProtectMemory</c> function. When you have
|
|
|
|
|
/// finished using the sensitive information, clear it from memory by calling the SecureZeroMemory function.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Use the CRYPTPROTECTMEMORY_CROSS_PROCESS or CRYPTPROTECTMEMORY_SAME_LOGON flag if you use RPC or LRPC to pass encrypted data to
|
|
|
|
|
/// another process. The receiving process must specify the same flag to decrypt the data. Also, use these flags if you use shared memory.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// If the client uses the CRYPTPROTECTMEMORY_SAME_LOGON flag, the server must impersonate the client (RpcImpersonateClient) before
|
|
|
|
|
/// decrypting the memory.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>Examples</para>
|
|
|
|
|
/// <para>The following example calls the <c>CryptProtectMemory</c> function to encrypt data that is in memory.</para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectmemory DPAPI_IMP BOOL CryptProtectMemory( LPVOID
|
|
|
|
|
// pDataIn, DWORD cbDataIn, DWORD dwFlags );
|
|
|
|
|
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "6b372552-87d4-4047-afa5-0d1113348289")]
|
|
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
|
|
|
public static extern bool CryptProtectMemory(IntPtr pDataIn, uint cbDataIn, CryptProtectMemoryFlags dwFlags);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>CryptUnprotectData</c> function decrypts and does an integrity check of the data in a DATA_BLOB structure. Usually, the
|
|
|
|
|
/// only user who can decrypt the data is a user with the same logon credentials as the user who encrypted the data. In addition,
|
|
|
|
|
/// the encryption and decryption must be done on the same computer. For information about exceptions, see the Remarks section of CryptProtectData.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pDataIn">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that holds the encrypted data. The <c>DATA_BLOB</c> structure's <c>cbData</c> member holds
|
|
|
|
|
/// the length of the <c>pbData</c> member's byte string that contains the text to be encrypted.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="ppszDataDescr">
|
|
|
|
|
/// A pointer to a string-readable description of the encrypted data included with the encrypted data. This parameter can be set to
|
|
|
|
|
/// <c>NULL</c>. When you have finished using ppszDataDescr, free it by calling the LocalFree function.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pOptionalEntropy">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used when the data was encrypted. This
|
|
|
|
|
/// parameter can be set to <c>NULL</c>; however, if an optional entropy <c>DATA_BLOB</c> structure was used in the encryption
|
|
|
|
|
/// phase, that same <c>DATA_BLOB</c> structure must be used for the decryption phase. For information about protecting passwords,
|
|
|
|
|
/// see Handling Passwords.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pvReserved">This parameter is reserved for future use and must be set to <c>NULL</c>.</param>
|
|
|
|
|
/// <param name="pPromptStruct">
|
|
|
|
|
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
|
|
|
|
|
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c>.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="dwFlags">
|
|
|
|
|
/// <para>
|
|
|
|
|
/// A <c>DWORD</c> value that specifies options for this function. This parameter can be zero, in which case no option is set, or
|
|
|
|
|
/// the following flag.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Value</term>
|
|
|
|
|
/// <term>Meaning</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// This flag is used for remote situations where the user interface (UI) is not an option. When this flag is set and UI is
|
|
|
|
|
/// specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
|
|
|
|
|
/// ERROR_PASSWORD_RESTRICTION code.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_VERIFY_PROTECTION</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// This flag verifies the protection of a protected BLOB. If the default protection level configured of the host is higher than the
|
|
|
|
|
/// current protection level for the BLOB, the function returns CRYPT_I_NEW_PROTECTION_REQUIRED to advise the caller to again
|
|
|
|
|
/// protect the plaintext contained in the BLOB.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pDataOut">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure where the function stores the decrypted data. When you have finished using the
|
|
|
|
|
/// <c>DATA_BLOB</c> structure, free its <c>pbData</c> member by calling the LocalFree function.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
|
|
|
|
|
/// <para>If the function fails, it returns <c>FALSE</c>.</para>
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The CryptProtectData function creates a session key when the data is encrypted. That key is derived again and used to decrypt
|
|
|
|
|
/// the data BLOB.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The Message Authentication Code (MAC) hash added to the encrypted data can be used to determine whether the encrypted data was
|
|
|
|
|
/// altered in any way. Any tampering results in the return of the ERROR_INVALID_DATA code.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// When you have finished using the DATA_BLOB structure, free its <c>pbData</c> member by calling the LocalFree function. Any
|
|
|
|
|
/// ppszDataDescr that is not <c>NULL</c> must also be freed by using <c>LocalFree</c>.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>When you have finished using sensitive information, clear it from memory by calling the SecureZeroMemory function.</para>
|
|
|
|
|
/// <para>Examples</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The following example shows decrypting encrypted data in a DATA_BLOB structure. This function does the decryption by using a
|
|
|
|
|
/// session key that the function creates by using the user's logon credentials. For another example that uses this function, see
|
|
|
|
|
/// Example C Program: Using CryptProtectData.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata DPAPI_IMP BOOL CryptUnprotectData( DATA_BLOB
|
|
|
|
|
// *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
|
|
|
|
|
// dwFlags, DATA_BLOB *pDataOut );
|
|
|
|
|
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "54eab3b0-d341-47c6-9c32-79328d7a7155")]
|
|
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
|
|
|
public static extern bool CryptUnprotectData(in CRYPTOAPI_BLOB pDataIn, [MarshalAs(UnmanagedType.LPWStr)] out IntPtr ppszDataDescr,
|
|
|
|
|
in CRYPTOAPI_BLOB pOptionalEntropy, [Optional] IntPtr pvReserved, in CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, CryptProtectFlags dwFlags, [Out] IntPtr pDataOut);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>CryptUnprotectData</c> function decrypts and does an integrity check of the data in a DATA_BLOB structure. Usually, the
|
|
|
|
|
/// only user who can decrypt the data is a user with the same logon credentials as the user who encrypted the data. In addition,
|
|
|
|
|
/// the encryption and decryption must be done on the same computer. For information about exceptions, see the Remarks section of CryptProtectData.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pDataIn">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that holds the encrypted data. The <c>DATA_BLOB</c> structure's <c>cbData</c> member holds
|
|
|
|
|
/// the length of the <c>pbData</c> member's byte string that contains the text to be encrypted.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="ppszDataDescr">
|
|
|
|
|
/// A pointer to a string-readable description of the encrypted data included with the encrypted data. This parameter can be set to
|
|
|
|
|
/// <c>NULL</c>. When you have finished using ppszDataDescr, free it by calling the LocalFree function.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pOptionalEntropy">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used when the data was encrypted. This
|
|
|
|
|
/// parameter can be set to <c>NULL</c>; however, if an optional entropy <c>DATA_BLOB</c> structure was used in the encryption
|
|
|
|
|
/// phase, that same <c>DATA_BLOB</c> structure must be used for the decryption phase. For information about protecting passwords,
|
|
|
|
|
/// see Handling Passwords.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pvReserved">This parameter is reserved for future use and must be set to <c>NULL</c>.</param>
|
|
|
|
|
/// <param name="pPromptStruct">
|
|
|
|
|
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
|
|
|
|
|
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c>.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="dwFlags">
|
|
|
|
|
/// <para>
|
|
|
|
|
/// A <c>DWORD</c> value that specifies options for this function. This parameter can be zero, in which case no option is set, or
|
|
|
|
|
/// the following flag.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Value</term>
|
|
|
|
|
/// <term>Meaning</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// This flag is used for remote situations where the user interface (UI) is not an option. When this flag is set and UI is
|
|
|
|
|
/// specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
|
|
|
|
|
/// ERROR_PASSWORD_RESTRICTION code.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_VERIFY_PROTECTION</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// This flag verifies the protection of a protected BLOB. If the default protection level configured of the host is higher than the
|
|
|
|
|
/// current protection level for the BLOB, the function returns CRYPT_I_NEW_PROTECTION_REQUIRED to advise the caller to again
|
|
|
|
|
/// protect the plaintext contained in the BLOB.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pDataOut">
|
|
|
|
|
/// A pointer to a DATA_BLOB structure where the function stores the decrypted data. When you have finished using the
|
|
|
|
|
/// <c>DATA_BLOB</c> structure, free its <c>pbData</c> member by calling the LocalFree function.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
|
|
|
|
|
/// <para>If the function fails, it returns <c>FALSE</c>.</para>
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The CryptProtectData function creates a session key when the data is encrypted. That key is derived again and used to decrypt
|
|
|
|
|
/// the data BLOB.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The Message Authentication Code (MAC) hash added to the encrypted data can be used to determine whether the encrypted data was
|
|
|
|
|
/// altered in any way. Any tampering results in the return of the ERROR_INVALID_DATA code.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// When you have finished using the DATA_BLOB structure, free its <c>pbData</c> member by calling the LocalFree function. Any
|
|
|
|
|
/// ppszDataDescr that is not <c>NULL</c> must also be freed by using <c>LocalFree</c>.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>When you have finished using sensitive information, clear it from memory by calling the SecureZeroMemory function.</para>
|
|
|
|
|
/// <para>Examples</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The following example shows decrypting encrypted data in a DATA_BLOB structure. This function does the decryption by using a
|
|
|
|
|
/// session key that the function creates by using the user's logon credentials. For another example that uses this function, see
|
|
|
|
|
/// Example C Program: Using CryptProtectData.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata DPAPI_IMP BOOL CryptUnprotectData( DATA_BLOB
|
|
|
|
|
// *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
|
|
|
|
|
// dwFlags, DATA_BLOB *pDataOut );
|
|
|
|
|
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "54eab3b0-d341-47c6-9c32-79328d7a7155")]
|
|
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
|
|
|
public static extern bool CryptUnprotectData(in CRYPTOAPI_BLOB pDataIn, [Optional] IntPtr ppszDataDescr,
|
|
|
|
|
[Optional] IntPtr pOptionalEntropy, [Optional] IntPtr pvReserved, [Optional] IntPtr pPromptStruct, CryptProtectFlags dwFlags, [Out] IntPtr pDataOut);
|
|
|
|
|
|
|
|
|
|
/// <summary>The <c>CryptUnprotectMemory</c> function decrypts memory that was encrypted using the CryptProtectMemory function.</summary>
|
|
|
|
|
/// <param name="pDataIn">
|
|
|
|
|
/// A pointer to the block of memory to decrypt. The cbData parameter specifies the number of bytes that the function will attempt
|
|
|
|
|
/// to decrypt. If the data contained in the memory space is smaller than the number of bytes specified, the function will attempt
|
|
|
|
|
/// to decrypt data outside of the intended block. If it is larger than cbData bytes, then only the first cbData bytes will be decrypted.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="cbDataIn">
|
|
|
|
|
/// Number of bytes of memory pointed to by the pData parameter to decrypt. The number of bytes must be a multiple of the
|
|
|
|
|
/// <c>CRYPTPROTECTMEMORY_BLOCK_SIZE</c> constant defined in Wincrypt.h.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="dwFlags">
|
|
|
|
|
/// <para>This parameter can be one of the following flags. You must specify the same flag when encrypting and decrypting the memory.</para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Value</term>
|
|
|
|
|
/// <term>Meaning</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECTMEMORY_SAME_PROCESS</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt the data.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECTMEMORY_CROSS_PROCESS</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECTMEMORY_SAME_LOGON</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// Use the same logon credentials to encrypt and decrypt memory in different processes. An application running in a different
|
|
|
|
|
/// process will be able to decrypt the data. However, the process must run as the same user that encrypted the data and in the same
|
|
|
|
|
/// logon session.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
|
|
|
|
|
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Using CryptProtectMemory and CryptUnprotectMemory for password encryption is not secure because the data exists as plaintext in
|
|
|
|
|
/// memory before it is encrypted and at any time the caller decrypts it for use.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// You must encrypt and decrypt the memory during the same boot session. If the computer is restarted before you call the
|
|
|
|
|
/// <c>CryptUnprotectMemory</c> function, you will not be able to decrypt the data.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// You must pass the same flag to <c>CryptUnprotectMemory</c> and CryptProtectMemory. If you pass different flags, the
|
|
|
|
|
/// <c>CryptUnprotectMemory</c> function succeeds; however, the result is unpredictable.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>When you have finished using the sensitive information, clear it from memory by calling the SecureZeroMemory function.</para>
|
|
|
|
|
/// <para>Examples</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The following example calls the <c>CryptUnprotectMemory</c> function to decrypt data that is in memory. The example assumes the
|
|
|
|
|
/// variable pEncryptedText points to a string that has been encrypted using the CryptProtectMemory function.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectmemory DPAPI_IMP BOOL CryptUnprotectMemory(
|
|
|
|
|
// LPVOID pDataIn, DWORD cbDataIn, DWORD dwFlags );
|
|
|
|
|
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "1c7980ac-4e9e-43fd-b6d7-c0d0a69c8040")]
|
|
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
|
|
|
public static extern bool CryptUnprotectMemory(IntPtr pDataIn, uint cbDataIn, CryptProtectMemoryFlags dwFlags);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>CryptUpdateProtectedState</c> function migrates the current user's master keys after the user's security identifier (SID)
|
|
|
|
|
/// has changed. This function can be used to preserve encrypted data after a user has been moved from one domain to another.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pOldSid">
|
|
|
|
|
/// <para>
|
|
|
|
|
/// The address of a SID structure that contains the user's previous SID. This SID is used to locate the old master keys. If this
|
|
|
|
|
/// parameter is <c>NULL</c>, the master keys for the current user SID are migrated.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>Either this parameter or the pwszOldPassword parameter may be <c>NULL</c>, but not both.</para>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pwszOldPassword">
|
|
|
|
|
/// <para>
|
|
|
|
|
/// A pointer to a null-terminated Unicode string that contains the user's password before the SID was changed. This password is
|
|
|
|
|
/// used to decrypt the old master keys. If this parameter is <c>NULL</c>, the password of the current user will be used.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>Either this parameter or the pOldSid parameter may be <c>NULL</c>, but not both.</para>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="dwFlags">Not used. Must be zero.</param>
|
|
|
|
|
/// <param name="pdwSuccessCount">
|
|
|
|
|
/// The address of a <c>DWORD</c> variable that receives the number of master keys that were successfully migrated.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="pdwFailureCount">
|
|
|
|
|
/// <para>The address of a <c>DWORD</c> variable that receives the number of master keys that could not be decrypted.</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// It is not necessarily an error if one or more master keys cannot be decrypted. Some users may possess master keys that are
|
|
|
|
|
/// stagnant and could not have been decrypted for a long time. One way that this can happen is when the password of a local user
|
|
|
|
|
/// has been administratively reset.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// If the function fails, the return value is <c>FALSE</c>. For extended error information, call GetLastError. Some possible error
|
|
|
|
|
/// codes include the following.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Return code</term>
|
|
|
|
|
/// <term>Description</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>ERROR_INVALID_PARAMETER</term>
|
|
|
|
|
/// <term>One of the parameters contains a value that is not valid.</term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>ERROR_OUTOFMEMORY</term>
|
|
|
|
|
/// <term>A memory allocation failure occurred.</term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>ERROR_ENCRYPTION_FAILED</term>
|
|
|
|
|
/// <term>The old password could not be encrypted.</term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// This function decrypts all of the user's master keys in the old master key directory, using the previous password, and stores
|
|
|
|
|
/// them in the user's current master key directory, encrypted with the user's current password.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>This function must be called from the user account that the keys are being migrated to.</para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// If this function is able to successfully migrate an old master key, it will automatically delete the old master key. Master keys
|
|
|
|
|
/// that cannot be decrypted are not deleted.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptupdateprotectedstate DPAPI_IMP BOOL
|
|
|
|
|
// CryptUpdateProtectedState( PSID pOldSid, LPCWSTR pwszOldPassword, DWORD dwFlags, DWORD *pdwSuccessCount, DWORD *pdwFailureCount );
|
|
|
|
|
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "f32e8fcd-6b5b-4a43-b3f9-77e17c84deca")]
|
|
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
|
|
|
public static extern bool CryptUpdateProtectedState([Optional] PSID pOldSid, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszOldPassword, [Optional] uint dwFlags, out uint pdwSuccessCount, out uint pdwFailureCount);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>CRYPTPROTECT_PROMPTSTRUCT</c> structure provides the text of a prompt and information about when and where that prompt is
|
|
|
|
|
/// to be displayed when using the CryptProtectData and CryptUnprotectData functions.
|
|
|
|
|
/// </summary>
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/ns-dpapi-cryptprotect_promptstruct typedef struct
|
|
|
|
|
// _CRYPTPROTECT_PROMPTSTRUCT { DWORD cbSize; DWORD dwPromptFlags; HWND hwndApp; LPCWSTR szPrompt; } CRYPTPROTECT_PROMPTSTRUCT, *PCRYPTPROTECT_PROMPTSTRUCT;
|
|
|
|
|
[PInvokeData("dpapi.h", MSDNShortId = "412ce598-a7c9-446d-bd98-6583a20d6cd7")]
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
|
public struct CRYPTPROTECT_PROMPTSTRUCT
|
|
|
|
|
{
|
|
|
|
|
/// <summary>The size, in bytes, of this structure.</summary>
|
|
|
|
|
public uint cbSize;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// <c>DWORD</c> flags that indicate when prompts to the user are to be displayed. Current <c>dwPromptFlags</c> values are as follows.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <list type="table">
|
|
|
|
|
/// <listheader>
|
|
|
|
|
/// <term>Value</term>
|
|
|
|
|
/// <term>Meaning</term>
|
|
|
|
|
/// </listheader>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_PROMPT_ON_PROTECT</term>
|
|
|
|
|
/// <term>This flag is used to provide the prompt for the protect phase.</term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// <item>
|
|
|
|
|
/// <term>CRYPTPROTECT_PROMPT_ON_UNPROTECT</term>
|
|
|
|
|
/// <term>
|
|
|
|
|
/// This flag can be combined with CRYPTPROTECT_PROMPT_ON_PROTECT to enforce the UI (user interface) policy of the caller. When
|
|
|
|
|
/// CryptUnprotectData is called, the dwPromptFlags specified in the CryptProtectData call are enforced.
|
|
|
|
|
/// </term>
|
|
|
|
|
/// </item>
|
|
|
|
|
/// </list>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public CryptProtectPrompt dwPromptFlags;
|
|
|
|
|
|
|
|
|
|
/// <summary>Window handle to the parent window.</summary>
|
|
|
|
|
public HWND hwndApp;
|
|
|
|
|
|
|
|
|
|
/// <summary>A string containing the text of a prompt to be displayed.</summary>
|
|
|
|
|
[MarshalAs(UnmanagedType.LPWStr)] public string szPrompt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|