using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { /// Methods and data types found in Crypt32.dll. public static partial class Crypt32 { /// Flags for CryptProtectData. [PInvokeData("dpapi.h", MSDNShortId = "765a68fd-f105-49fc-a738-4a8129eb0770")] [Flags] public enum CryptProtectFlags { /// /// 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. /// CRYPTPROTECT_UI_FORBIDDEN = 0x1, /// /// 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. /// CRYPTPROTECT_LOCAL_MACHINE = 0x4, /// /// Force credential synchronize during CryptProtectData(). Synchronize is the only operation that occurs during this operation. /// CRYPTPROTECT_CRED_SYNC = 0x8, /// Generate an Audit on protect and unprotect operations. CRYPTPROTECT_AUDIT = 0x10, /// Protect data with a non-recoverable key. CRYPTPROTECT_NO_RECOVERY = 0x20, /// Verify the protection of a protected blob. CRYPTPROTECT_VERIFY_PROTECTION = 0x40, /// Regenerate the local machine protection. CRYPTPROTECT_CRED_REGENERATE = 0x80 } /// Flags for CryptProtectMemory and CryptUnprotectMemory [PInvokeData("dpapi.h", MSDNShortId = "6b372552-87d4-4047-afa5-0d1113348289")] [Flags] public enum CryptProtectMemoryFlags { /// /// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt /// the data. /// CRYPTPROTECTMEMORY_SAME_PROCESS = 0x00, /// /// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data. /// CRYPTPROTECTMEMORY_CROSS_PROCESS = 0x01, /// /// 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. /// CRYPTPROTECTMEMORY_SAME_LOGON = 0x02, } /// Flags that indicate when prompts to the user are to be displayed. [PInvokeData("dpapi.h", MSDNShortId = "412ce598-a7c9-446d-bd98-6583a20d6cd7")] [Flags] public enum CryptProtectPrompt : uint { /// /// 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. /// CRYPTPROTECT_PROMPT_ON_UNPROTECT = 0x1, /// This flag is used to provide the prompt for the protect phase. CRYPTPROTECT_PROMPT_ON_PROTECT = 0x2, /// Reserved. CRYPTPROTECT_PROMPT_RESERVED = 0x04, /// Default to strong variant UI protection (user supplied password currently). CRYPTPROTECT_PROMPT_STRONG = 0x08, /// Require strong variant UI protection (user supplied password currently). CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 0x10, } /// /// The CryptProtectData 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. /// /// A pointer to a DATA_BLOB structure that contains the plaintext to be encrypted. /// /// 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 NULL. /// /// /// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used to encrypt the data. The /// DATA_BLOB structure used in the encryption phase must also be used in the decryption phase. This parameter can be set to /// NULL for no additional entropy. For information about protecting passwords, see Handling Passwords. /// /// Reserved for future use and must be set to NULL. /// /// 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 NULL in both the encryption and decryption phases. /// /// /// This parameter can be one of the following flags. /// /// /// Value /// Meaning /// /// /// CRYPTPROTECT_LOCAL_MACHINE /// /// 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. /// /// /// /// CRYPTPROTECT_UI_FORBIDDEN /// /// 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. /// /// /// /// CRYPTPROTECT_AUDIT /// This flag generates an audit on protect and unprotect operations. /// /// /// /// /// A pointer to a DATA_BLOB structure that receives the encrypted data. When you have finished using the DATA_BLOB /// structure, free its pbData member by calling the LocalFree function. /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// /// /// /// 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. /// /// /// 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. /// /// /// The function creates a session key to perform the encryption. The session key is derived again when the data is to be decrypted. /// /// /// The function also adds a Message Authentication Code (MAC) (keyed integrity check) to the encrypted data to guard against data tampering. /// /// To encrypt memory for temporary use in the same process or across processes, call the CryptProtectMemory function. /// Examples /// /// The following example shows encryption of the data in a DATA_BLOB structure. The CryptProtectData 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. /// /// // 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); /// /// The CryptProtectData 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. /// /// A pointer to a DATA_BLOB structure that contains the plaintext to be encrypted. /// /// 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 NULL. /// /// /// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used to encrypt the data. The /// DATA_BLOB structure used in the encryption phase must also be used in the decryption phase. This parameter can be set to /// NULL for no additional entropy. For information about protecting passwords, see Handling Passwords. /// /// Reserved for future use and must be set to NULL. /// /// 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 NULL in both the encryption and decryption phases. /// /// /// This parameter can be one of the following flags. /// /// /// Value /// Meaning /// /// /// CRYPTPROTECT_LOCAL_MACHINE /// /// 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. /// /// /// /// CRYPTPROTECT_UI_FORBIDDEN /// /// 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. /// /// /// /// CRYPTPROTECT_AUDIT /// This flag generates an audit on protect and unprotect operations. /// /// /// /// /// A pointer to a DATA_BLOB structure that receives the encrypted data. When you have finished using the DATA_BLOB /// structure, free its pbData member by calling the LocalFree function. /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// /// /// /// 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. /// /// /// 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. /// /// /// The function creates a session key to perform the encryption. The session key is derived again when the data is to be decrypted. /// /// /// The function also adds a Message Authentication Code (MAC) (keyed integrity check) to the encrypted data to guard against data tampering. /// /// To encrypt memory for temporary use in the same process or across processes, call the CryptProtectMemory function. /// Examples /// /// The following example shows encryption of the data in a DATA_BLOB structure. The CryptProtectData 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. /// /// // 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); /// /// The CryptProtectMemory function encrypts memory to prevent others from viewing sensitive information in your process. For /// example, use the CryptProtectMemory 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. /// /// /// 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. /// /// /// Number of bytes of memory pointed to by the pData parameter to encrypt. The number of bytes must be a multiple of the /// CRYPTPROTECTMEMORY_BLOCK_SIZE constant defined in Wincrypt.h. /// /// /// This parameter can be one of the following flags. You must specify the same flag when encrypting and decrypting the memory. /// /// /// Value /// Meaning /// /// /// CRYPTPROTECTMEMORY_SAME_PROCESS /// /// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt the data. /// /// /// /// CRYPTPROTECTMEMORY_CROSS_PROCESS /// /// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data. /// /// /// /// CRYPTPROTECTMEMORY_SAME_LOGON /// /// 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. /// /// /// /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// /// /// /// 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. /// /// /// Typically, you use the CryptProtectMemory 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. /// /// /// Call the CryptUnprotectMemory function to decrypt memory encrypted with the CryptProtectMemory function. When you have /// finished using the sensitive information, clear it from memory by calling the SecureZeroMemory function. /// /// /// 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. /// /// /// If the client uses the CRYPTPROTECTMEMORY_SAME_LOGON flag, the server must impersonate the client (RpcImpersonateClient) before /// decrypting the memory. /// /// Examples /// The following example calls the CryptProtectMemory function to encrypt data that is in memory. /// // 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); /// /// The CryptUnprotectData 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. /// /// /// A pointer to a DATA_BLOB structure that holds the encrypted data. The DATA_BLOB structure's cbData member holds /// the length of the pbData member's byte string that contains the text to be encrypted. /// /// /// A pointer to a string-readable description of the encrypted data included with the encrypted data. This parameter can be set to /// NULL. When you have finished using ppszDataDescr, free it by calling the LocalFree function. /// /// /// 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 NULL; however, if an optional entropy DATA_BLOB structure was used in the encryption /// phase, that same DATA_BLOB structure must be used for the decryption phase. For information about protecting passwords, /// see Handling Passwords. /// /// This parameter is reserved for future use and must be set to NULL. /// /// 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 NULL. /// /// /// /// A DWORD value that specifies options for this function. This parameter can be zero, in which case no option is set, or /// the following flag. /// /// /// /// Value /// Meaning /// /// /// CRYPTPROTECT_UI_FORBIDDEN /// /// 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. /// /// /// /// CRYPTPROTECT_VERIFY_PROTECTION /// /// 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. /// /// /// /// /// /// A pointer to a DATA_BLOB structure where the function stores the decrypted data. When you have finished using the /// DATA_BLOB structure, free its pbData member by calling the LocalFree function. /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. /// /// /// /// The CryptProtectData function creates a session key when the data is encrypted. That key is derived again and used to decrypt /// the data BLOB. /// /// /// 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. /// /// /// When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function. Any /// ppszDataDescr that is not NULL must also be freed by using LocalFree. /// /// When you have finished using sensitive information, clear it from memory by calling the SecureZeroMemory function. /// Examples /// /// 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. /// /// // 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); /// /// The CryptUnprotectData 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. /// /// /// A pointer to a DATA_BLOB structure that holds the encrypted data. The DATA_BLOB structure's cbData member holds /// the length of the pbData member's byte string that contains the text to be encrypted. /// /// /// A pointer to a string-readable description of the encrypted data included with the encrypted data. This parameter can be set to /// NULL. When you have finished using ppszDataDescr, free it by calling the LocalFree function. /// /// /// 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 NULL; however, if an optional entropy DATA_BLOB structure was used in the encryption /// phase, that same DATA_BLOB structure must be used for the decryption phase. For information about protecting passwords, /// see Handling Passwords. /// /// This parameter is reserved for future use and must be set to NULL. /// /// 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 NULL. /// /// /// /// A DWORD value that specifies options for this function. This parameter can be zero, in which case no option is set, or /// the following flag. /// /// /// /// Value /// Meaning /// /// /// CRYPTPROTECT_UI_FORBIDDEN /// /// 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. /// /// /// /// CRYPTPROTECT_VERIFY_PROTECTION /// /// 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. /// /// /// /// /// /// A pointer to a DATA_BLOB structure where the function stores the decrypted data. When you have finished using the /// DATA_BLOB structure, free its pbData member by calling the LocalFree function. /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. /// /// /// /// The CryptProtectData function creates a session key when the data is encrypted. That key is derived again and used to decrypt /// the data BLOB. /// /// /// 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. /// /// /// When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function. Any /// ppszDataDescr that is not NULL must also be freed by using LocalFree. /// /// When you have finished using sensitive information, clear it from memory by calling the SecureZeroMemory function. /// Examples /// /// 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. /// /// // 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); /// The CryptUnprotectMemory function decrypts memory that was encrypted using the CryptProtectMemory function. /// /// 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. /// /// /// Number of bytes of memory pointed to by the pData parameter to decrypt. The number of bytes must be a multiple of the /// CRYPTPROTECTMEMORY_BLOCK_SIZE constant defined in Wincrypt.h. /// /// /// This parameter can be one of the following flags. You must specify the same flag when encrypting and decrypting the memory. /// /// /// Value /// Meaning /// /// /// CRYPTPROTECTMEMORY_SAME_PROCESS /// /// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt the data. /// /// /// /// CRYPTPROTECTMEMORY_CROSS_PROCESS /// /// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data. /// /// /// /// CRYPTPROTECTMEMORY_SAME_LOGON /// /// 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. /// /// /// /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// /// /// /// 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. /// /// /// You must encrypt and decrypt the memory during the same boot session. If the computer is restarted before you call the /// CryptUnprotectMemory function, you will not be able to decrypt the data. /// /// /// You must pass the same flag to CryptUnprotectMemory and CryptProtectMemory. If you pass different flags, the /// CryptUnprotectMemory function succeeds; however, the result is unpredictable. /// /// When you have finished using the sensitive information, clear it from memory by calling the SecureZeroMemory function. /// Examples /// /// The following example calls the CryptUnprotectMemory 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. /// /// // 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); /// /// The CryptUpdateProtectedState 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. /// /// /// /// 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 NULL, the master keys for the current user SID are migrated. /// /// Either this parameter or the pwszOldPassword parameter may be NULL, but not both. /// /// /// /// 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 NULL, the password of the current user will be used. /// /// Either this parameter or the pOldSid parameter may be NULL, but not both. /// /// Not used. Must be zero. /// /// The address of a DWORD variable that receives the number of master keys that were successfully migrated. /// /// /// The address of a DWORD variable that receives the number of master keys that could not be decrypted. /// /// 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. /// /// /// /// If the function succeeds, the return value is TRUE. /// /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error /// codes include the following. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. /// /// /// ERROR_OUTOFMEMORY /// A memory allocation failure occurred. /// /// /// ERROR_ENCRYPTION_FAILED /// The old password could not be encrypted. /// /// /// /// /// /// 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. /// /// This function must be called from the user account that the keys are being migrated to. /// /// 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. /// /// // 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); /// /// The CRYPTPROTECT_PROMPTSTRUCT 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. /// // 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 { /// The size, in bytes, of this structure. public uint cbSize; /// /// /// DWORD flags that indicate when prompts to the user are to be displayed. Current dwPromptFlags values are as follows. /// /// /// /// Value /// Meaning /// /// /// CRYPTPROTECT_PROMPT_ON_PROTECT /// This flag is used to provide the prompt for the protect phase. /// /// /// CRYPTPROTECT_PROMPT_ON_UNPROTECT /// /// 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. /// /// /// /// public CryptProtectPrompt dwPromptFlags; /// Window handle to the parent window. public HWND hwndApp; /// A string containing the text of a prompt to be displayed. [MarshalAs(UnmanagedType.LPWStr)] public string szPrompt; } } }