using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Vanara.InteropServices; using static Vanara.PInvoke.Crypt32; namespace Vanara.PInvoke { public static partial class AdvApi32 { private delegate bool CryptGetValueMethod(THandle hKey, TEnum dwParam, IntPtr pbData, ref uint pdwDataLen, uint dwFlags) where THandle : struct where TEnum : Enum; /// /// The PROV_RSA_FULL provider type supports both digital signatures and data encryption. It is considered a general purpose CSP. The /// RSA public key algorithm is used for all public key operations. /// public const uint PROV_RSA_FULL = 1; /// /// The PROV_RSA_SIG provider type is a subset of PROV_RSA_FULL. It supports only those functions and algorithms required for hashes /// and digital signatures. /// public const uint PROV_RSA_SIG = 2; /// /// Supports hashes and digital signatures. The signature algorithm specified by the PROV_DSS provider type is the Digital Signature /// Algorithm (DSA). /// public const uint PROV_DSS = 3; /// /// The PROV_FORTEZZA provider type contains a set of cryptographic protocols and algorithms owned by the National Institute of /// Standards and Technology (NIST). /// public const uint PROV_FORTEZZA = 4; /// /// Designed for the cryptographic needs of the Exchange mail application and other applications compatible with Microsoft Mail. /// public const uint PROV_MS_EXCHANGE = 5; /// The PROV_SSL provider type supports the Secure Sockets Layer (SSL) protocol. public const uint PROV_SSL = 6; /// Supports both RSA and Schannel protocols. public const uint PROV_RSA_SCHANNEL = 12; /// A superset of the PROV_DSS provider type with Diffie-Hellman key exchange. public const uint PROV_DSS_DH = 13; /// public const uint PROV_EC_ECDSA_SIG = 14; /// public const uint PROV_EC_ECNRA_SIG = 15; /// public const uint PROV_EC_ECDSA_FULL = 16; /// public const uint PROV_EC_ECNRA_FULL = 17; /// Supports both Diffie-Hellman and Schannel protocols. public const uint PROV_DH_SCHANNEL = 18; /// public const uint PROV_SPYRUS_LYNKS = 20; /// public const uint PROV_RNG = 21; /// public const uint PROV_INTEL_SEC = 22; /// public const uint PROV_REPLACE_OWF = 23; /// Supports the same as PROV_RSA_FULL with additional AES encryption capability. public const uint PROV_RSA_AES = 24; /// public const uint PROV_STT_MER = 7; /// public const uint PROV_STT_ACQ = 8; /// public const uint PROV_STT_BRND = 9; /// public const uint PROV_STT_ROOT = 10; /// public const uint PROV_STT_ISS = 11; /// Flag values for . [PInvokeData("wincrypt.h", MSDNShortId = "57e13662-3189-4f8d-b90a-d1fbdc09b63c")] [Flags] public enum CryptAcquireContextFlags : uint { /// /// This option is intended for applications that are using ephemeral keys, or applications that do not require access to /// persisted private keys, such as applications that perform only hashing, encryption, and digital signature verification. Only /// applications that create signatures or decrypt messages need access to a private key. In most cases, this flag should be /// set. For file-based CSPs, when this flag is set, the pszContainer parameter must be set to NULL. The application has no /// access to the persisted private keys of public/private key pairs. When this flag is set, temporary public/private key pairs /// can be created, but they are not persisted. For hardware-based CSPs, such as a smart card CSP, if the pszContainer parameter /// is NULL or blank, this flag implies that no access to any keys is required, and that no UI should be presented to the user. /// This form is used to connect to the CSP to query its capabilities but not to actually use its keys. If the pszContainer /// parameter is not NULL and not blank, then this flag implies that access to only the publicly available information within /// the specified container is required. The CSP should not ask for a PIN. Attempts to access private information (for example, /// the CryptSignHash function) will fail. When CryptAcquireContext is called, many CSPs require input from the owning user /// before granting access to the private keys in the key container. For example, the private keys can be encrypted, requiring a /// password from the user before they can be used. However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private /// keys is not required and the user interface can be bypassed. /// CRYPT_VERIFYCONTEXT = 0xF0000000, /// /// Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the /// default name is created. /// CRYPT_NEWKEYSET = 0x00000008, /// /// Delete the key container specified by pszContainer. If pszContainer is NULL, the key container with the default name is /// deleted. All key pairs in the key container are also destroyed. When this flag is set, the value returned in phProv is /// undefined, and thus, the CryptReleaseContext function need not be called afterward. /// CRYPT_DELETEKEYSET = 0x00000010, /// /// By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are /// stored in the user's profile. A key container created without this flag by an administrator can be accessed only by the user /// creating the key container and a user with administration privileges. Windows XP: A key container created without this flag /// by an administrator can be accessed only by the user creating the key container and the local system account. A key /// container created without this flag by a user that is not an administrator can be accessed only by the user creating the key /// container and the local system account. The CRYPT_MACHINE_KEYSET flag can be combined with all of the other flags to /// indicate that the key container of interest is a computer key container and the CSP treats it as such. For Base Providers, /// this means that the keys are stored locally on the computer that created the key container. If a key container is to be a /// computer container, the CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the /// computer container. The key container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its /// creator and by a user with administrator privileges unless access rights to the container are granted using /// CryptSetProvParam. Windows XP: The key container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only /// by its creator and by the local system account unless access rights to the container are granted using CryptSetProvParam. /// The key container created with CRYPT_MACHINE_KEYSET by a user that is not an administrator can be accessed only by its /// creator and by the local system account unless access rights to the container are granted using CryptSetProvParam. The /// CRYPT_MACHINE_KEYSET flag is useful when the user is accessing from a service or user account that did not log on /// interactively. When key containers are created, most CSPs do not automatically create any public/private key pairs. These /// keys must be created as a separate step with the CryptGenKey function. /// CRYPT_MACHINE_KEYSET = 0x00000020, /// /// The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI /// to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error. In addition, if calls are made to /// CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls /// fail and the CSP sets NTE_SILENT_CONTEXT. CRYPT_SILENT is intended for use with applications for which the UI cannot be /// displayed by the CSP. /// CRYPT_SILENT = 0x00000040, /// /// Obtains a context for a smart card CSP that can be used for hashing and symmetric key operations but cannot be used for any /// operation that requires authentication to a smart card using a PIN. This type of context is most often used to perform /// operations on an empty smart card, such as setting the PIN by using CryptSetProvParam. This flag can only be used with smart /// card CSPs. Windows Server 2003 and Windows XP: This flag is not supported. /// CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080, } /// Flags for CryptDecrypt. [PInvokeData("wincrypt.h", MSDNShortId = "7c3d2838-6fd1-4f6c-9586-8b94b459a31a")] [Flags] public enum CryptDecryptFlags { /// /// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the /// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag. /// CRYPT_OAEP = 0x00000040, /// /// Perform the decryption on the BLOB without checking the padding. This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_OAEP flag. /// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK = 0x00000020, } /// Flags for CryptEncrypt. [PInvokeData("wincrypt.h", MSDNShortId = "697c4960-552b-4c3a-95cf-4632af56945b")] [Flags] public enum CryptEncryptFlags { /// /// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the /// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag. /// CRYPT_OAEP = 0x00000040, } /// Flags for . [PInvokeData("wincrypt.h", MSDNShortId = "8a7c7b46-3bea-4043-b568-6d91d6335737")] [Flags] public enum CryptExportKeyFlags { /// This flag causes this function to export version 3 of a BLOB type. CRYPT_BLOB_VER3 = 0x00000080, /// This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only. CRYPT_DESTROYKEY = 0x00000004, /// /// This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs. /// CRYPT_OAEP = 0x00000040, /// /// The first eight bytes of the RSA encryption block padding must be set to 0x03 rather than to random data. This prevents /// version rollback attacks and is discussed in the SSL3 specification. This flag is available for Schannel CSPs only. /// CRYPT_SSL2_FALLBACK = 0x00000002, /// This flag is not used. CRYPT_Y_ONLY = 0x00000001, /// CRYPT_IPSEC_HMAC_KEY = 0x00000100, } /// Flags for and . [PInvokeData("wincrypt.h", MSDNShortId = "b65dd856-2dfa-4cda-9b2f-b32f3c291470")] [Flags] public enum CryptGenKeyFlags : uint { /// /// If this flag is set, the session key can be transferred out of the CSP into a key BLOB through the CryptExportKey function. /// Because keys generally must be exportable, this flag should usually be set. /// /// If this flag is not set, then the session key is not exportable. This means the key is available only within the current /// session and only the application that created it is able to use it. /// /// This flag does not apply to public/private key pairs. /// CRYPT_EXPORTABLE = 0x00000001, /// /// If this flag is set, the user is notified through a dialog box or another method when certain actions are attempting to use /// this key. The precise behavior is specified by the CSP being used. If the provider context was opened with the CRYPT_SILENT /// flag set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT. /// CRYPT_USER_PROTECTED = 0x00000002, /// /// Typically, when a session key is made from a hash value, there are a number of leftover bits. For example, if the hash value /// is 128 bits and the session key is 40 bits, there will be 88 bits left over. /// /// If this flag is set, then the key is assigned a salt value based on the unused hash value bits. You can retrieve this salt /// value by using the CryptGetKeyParam function with the dwParam parameter set to KP_SALT. /// /// If this flag is not set, then the key is given a salt value of zero. /// /// When keys with nonzero salt values are exported (by using CryptExportKey), the salt value must also be obtained and kept /// with the key BLOB. /// /// CRYPT_CREATE_SALT = 0x00000004, /// /// Some CSPs use session keys that are derived from multiple hash values. When this is the case, CryptDeriveKey must be called /// multiple times. /// /// If this flag is set, a new session key is not generated.Instead, the key specified by phKey is modified.The precise behavior /// of this flag is dependent on the type of key being generated and on the particular CSP being used. /// /// Microsoft cryptographic service providers ignore this flag. /// CRYPT_UPDATE_KEY = 0x00000008, /// /// This flag specifies that a no salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. /// CRYPT_NO_SALT = 0x00000010, /// /// This flag specifies an initial Diffie-Hellman or DSS key generation. This flag is useful only with Diffie-Hellman and DSS /// CSPs. When used, a default key length will be used unless a key length is specified in the upper 16 bits of the dwFlags /// parameter. If parameters that involve key lengths are set on a PREGEN Diffie-Hellman or DSS key using CryptSetKeyParam, the /// key lengths must be compatible with the key length set here. /// CRYPT_PREGEN = 0x00000040, /// This flag is not used. CRYPT_RECIPIENT = 0x00000010, /// This flag is not used. CRYPT_INITIATOR = 0x00000040, /// This flag is not used. CRYPT_ONLINE = 0x00000080, /// This flag is not used. CRYPT_SF = 0x00000100, /// This flag is not used. CRYPT_CREATE_IV = 0x00000200, /// This flag is not used. CRYPT_KEK = 0x00000400, /// This flag is not used. CRYPT_DATA_KEY = 0x00000800, /// This flag is not used. CRYPT_VOLATILE = 0x00001000, /// This flag is not used. CRYPT_SGCKEY = 0x00002000, /// This flag is not used. CRYPT_USER_PROTECTED_STRONG = 0x00100000, /// /// If this flag is set, the key can be exported until its handle is closed by a call to CryptDestroyKey. This allows newly /// generated keys to be exported upon creation for archiving or key recovery. After the handle is closed, the key is no longer exportable. /// CRYPT_ARCHIVABLE = 0x00004000, /// /// /// This flag specifies strong key protection. When this flag is set, the user is prompted to enter a password for the key when /// the key is created. The user will be prompted to enter the password whenever this key is used. /// /// /// This flag is only used by the CSPs that are provided by Microsoft. Third party CSPs will define their own behavior for /// strong key protection. /// /// /// Specifying this flag causes the same result as calling this function with the CRYPT_USER_PROTECTED flag when strong key /// protection is specified in the system registry. /// /// /// If this flag is specified and the provider handle in the hProv parameter was created by using the CRYPT_VERIFYCONTEXT or /// CRYPT_SILENT flag, this function will set the last error to NTE_SILENT_CONTEXT and return zero. /// /// Windows Server 2003 and Windows XP: This flag is not supported. /// CRYPT_FORCE_KEY_PROTECTION_HIGH = 0x00008000, /// /// This flag is used only with Schannel providers. If this flag is set, the key to be generated is a server-write key; /// otherwise, it is a client-write key. /// CRYPT_SERVER = 0x400, } /// Flags for . [Flags] public enum CryptHashSessionKeyFlags { /// /// When this flag is set, the bytes of the key are hashed in little-endian form. Note that by default (when dwFlags is zero), /// the bytes of the key are hashed in big-endian form. /// CRYPT_LITTLE_ENDIAN = 1 } /// Flags for and . [PInvokeData("wincrypt.h", MSDNShortId = "5d15641e-1ad7-441d-9423-65fd51de9812")] [Flags] public enum CryptProviderFlags { /// Returns the user-context default CSP of the specified type. CRYPT_USER_DEFAULT = 0x00000002, /// Returns the computer default CSP of the specified type. CRYPT_MACHINE_DEFAULT = 0x00000001, /// Can be used in conjunction with CRYPT_MACHINE_DEFAULT or CRYPT_USER_DEFAULT to delete the default. CRYPT_DELETE_DEFAULT = 0x00000004, } /// Flags for and . [PInvokeData("wincrypt.h", MSDNShortId = "3119eabc-90ff-42c6-b3fa-e8be625f6d1e")] [Flags] public enum CryptSignFlags { /// /// This flag is used with RSA providers. When verifying the signature, the hash object identifier (OID) is not expected to be /// present or checked. If this flag is not set, the hash OID in the default signature is verified as specified in the /// definition of DigestInfo in PKCS #7. /// CRYPT_NOHASHOID = 0x00000001, /// This flag is not used. CRYPT_TYPE2_FORMAT = 0x00000002, /// Use X.931 support for the FIPS 186-2–compliant version of RSA (rDSA). CRYPT_X931_FORMAT = 0x00000004, } /// Query type. [PInvokeData("wincrypt.h", MSDNShortId = "ed008c07-1a40-4075-bdaa-eb7f7e12d9c3")] public enum HashParam { /// /// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash. /// [CorrespondingType(typeof(ALG_ID), CorrespondingAction.Get)] [CorrespondingType(typeof(uint))] HP_ALGID = 0x0001, /// /// The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to /// the hash object earlier through the CryptHashData and CryptHashSessionKey functions. /// /// The CryptGetHashParam function completes the hash. After CryptGetHashParam has been called, no more data can be added to the /// hash. Additional calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash, /// CryptDestroyHash should be called to destroy the hash object. /// /// [CorrespondingType(typeof(byte[]))] [CorrespondingType(typeof(IntPtr))] HP_HASHVAL = 0x0002, /// /// DWORD value indicating the number of bytes in the hash value. This value will vary depending on the hash algorithm. /// Applications must retrieve this value just before the HP_HASHVAL value so the correct amount of memory can be allocated. /// [CorrespondingType(typeof(uint), CorrespondingAction.Get)] HP_HASHSIZE = 0x0004, /// /// A pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used. /// [CorrespondingType(typeof(HMAC_INFO), CorrespondingAction.Set)] HP_HMAC_INFO = 0x0005, /// /// Component of the function argument GOSTR3411_PRF. It takes various values ​​in client and server messages when implementing /// the TLS Handshake Protocol. /// [CorrespondingType(typeof(CRYPTOAPI_BLOB), CorrespondingAction.Set)] HP_TLS1PRF_LABEL = 0x0006, /// /// Component of the function argument GOSTR3411_PRF. It takes various values ​​in client and server messages when implementing /// the TLS Handshake Protocol. /// [CorrespondingType(typeof(CRYPTOAPI_BLOB), CorrespondingAction.Set)] HP_TLS1PRF_SEED = 0x0007, } /// Specifies the type of query being made. [PInvokeData("wincrypt.h", MSDNShortId = "07956d74-0e22-484b-9bf1-e0184a2ff32f")] public enum KeyParam { /// /// Retrieve the initialization vector of the key. The pbData parameter is a pointer to a BYTE array that receives the /// initialization vector. The size of this array is the block size, in bytes. For example, if the block length is 64 bits, the /// initialization vector consists of 8 bytes. /// KP_IV = 1, /// /// Retrieve the salt value of the key. The pbData parameter is a pointer to a BYTE array that receives the salt value in /// little-endian form. The size of the salt value varies depending on the CSP and algorithm being used. Salt values do not /// apply to public/private key pairs. /// KP_SALT = 2, /// /// /// Retrieve the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that /// identifies the padding method used by the cipher. This can be one of the following values. /// /// /// PKCS5_PADDING
Specifies the PKCS 5 (sec 6.2) padding method.
RANDOM_PADDING
The padding uses random /// numbers. This padding method is not supported by the Microsoft supplied CSPs.
ZERO_PADDING
The padding uses /// zeros. This padding method is not supported by the Microsoft supplied CSPs. ///
///
KP_PADDING = 3, /// /// /// Retrieve the cipher mode. The pbData parameter is a pointer to a DWORD value that receives a cipher mode identifier. For /// more information about cipher modes, see Data Encryption and Decryption. /// /// The following cipher mode identifiers are currently defined. /// /// CRYPT_MODE_CBC
The cipher mode is cipher block chaining.
CRYPT_MODE_CFB
The cipher mode is cipher feedback /// (CFB). Microsoft CSPs currently support only 8-bit feedback in cipher feedback mode.
CRYPT_MODE_ECB
The cipher /// mode is electronic codebook.
CRYPT_MODE_OFB
The cipher mode is Output Feedback (OFB). Microsoft CSPs currently /// do not support Output Feedback Mode.
CRYPT_MODE_CTS
The cipher mode is ciphertext stealing mode. ///
///
KP_MODE = 4, /// /// Retrieve the number of bits to feed back. The pbData parameter is a pointer to a DWORD value that receives the number of /// bits that are processed per cycle when the OFB or CFB cipher modes are used. /// KP_MODE_BITS = 5, /// /// /// Retrieve the key permissions. The pbData parameter is a pointer to a DWORD value that receives the permission flags for the key. /// /// /// The following permission identifiers are currently defined. The key permissions can be zero or a combination of one or more /// of the following values. /// /// /// CRYPT_ARCHIVE
Allow export during the lifetime of the handle of the key. This permission can be set only if it is /// already set in the internal permissions field of the key. Attempts to clear this permission are ignored.
CRYPT_DECRYPT ///
Allow decryption.
CRYPT_ENCRYPT
Allow encryption.
CRYPT_EXPORT
Allow the key to be exported. ///
CRYPT_EXPORT_KEY
Allow the key to be used for exporting keys.
CRYPT_IMPORT_KEY
Allow the key to be /// used for importing keys.
CRYPT_MAC
Allow Message Authentication Codes (MACs) to be used with key.
/// CRYPT_READ
Allow values to be read.
CRYPT_WRITE
Allow values to be set. ///
///
KP_PERMISSIONS = 6, /// /// Retrieve the key algorithm. The pbData parameter is a pointer to an ALG_ID value that receives the identifier of the /// algorithm that was specified when the key was created. /// /// When AT_KEYEXCHANGE or AT_SIGNATURE is specified for the Algid parameter of the CryptGenKey function, the algorithm /// identifiers that are used to generate the key depend on the provider used. For more information, see ALG_ID. /// /// KP_ALGID = 7, /// /// If a session key is specified by the hKey parameter, retrieve the block length of the key cipher. The pbData parameter is a /// pointer to a DWORD value that receives the block length, in bits. For stream ciphers, this value is always zero. /// /// If a public/private key pair is specified by hKey, retrieve the encryption granularity of the key pair.The pbData parameter /// is a pointer to a DWORD value that receives the encryption granularity, in bits.For example, the Microsoft Base /// Cryptographic Provider generates 512-bit RSA key pairs, so a value of 512 is returned for these keys. If the public key /// algorithm does not support encryption, the value retrieved is undefined. /// /// KP_BLOCKLEN = 8, /// /// Retrieve the actual length of the key. The pbData parameter is a pointer to a DWORD value that receives the key length, in /// bits. KP_KEYLEN can be used to get the length of any key type. Microsoft cryptographic service providers (CSPs) return a key /// length of 64 bits for CALG_DES, 128 bits for CALG_3DES_112, and 192 bits for CALG_3DES. These lengths are different from the /// lengths returned when you are enumerating algorithms with the dwParam value of the CryptGetProvParam function set to /// PP_ENUMALGS. The length returned by this call is the actual size of the key, including the parity bits included in the key. /// /// Microsoft CSPs that support the CALG_CYLINK_MEK ALG_ID return 64 bits for that algorithm. CALG_CYLINK_MEK is a 40-bit key /// but has parity and zeroed key bits to make the key length 64 bits. /// /// KP_KEYLEN = 9, /// KP_SALT_EX = 10, /// /// Retrieve the modulus prime number P of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in /// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// KP_P = 11, /// /// Retrieve the generator G of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in /// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// KP_G = 12, /// /// Retrieve the modulus prime number Q of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in /// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// KP_Q = 13, /// KP_X = 14, /// KP_Y = 15, /// KP_RA = 16, /// KP_RB = 17, /// KP_INFO = 18, /// /// Retrieve the effective key length of an RC2 key. The pbData parameter is a pointer to a DWORD value that receives the /// effective key length. /// KP_EFFECTIVE_KEYLEN = 19, /// KP_SCHANNEL_ALG = 20, /// KP_CLIENT_RANDOM = 21, /// KP_SERVER_RANDOM = 22, /// KP_RP = 23, /// KP_PRECOMP_MD5 = 24, /// KP_PRECOMP_SHA = 25, /// /// pbData is the address of a buffer that receives the X.509 certificate that has been encoded by using Distinguished Encoding /// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key. /// KP_CERTIFICATE = 26, /// KP_CLEAR_KEY = 27, /// KP_PUB_EX_LEN = 28, /// KP_PUB_EX_VAL = 29, /// /// This value is not used. /// /// Windows Vista, Windows Server 2003 and Windows XP: Retrieve the secret agreement value from an imported Diffie-Hellman /// algorithm key of type CALG_AGREEDKEY_ANY. The pbData parameter is the address of a buffer that receives the secret agreement /// value, in little-endian format. This buffer must be the same length as the key. The dwFlags parameter must be set to /// 0xF42A19B6. This property can only be retrieved by a thread running under the local system account.This property is /// available for use in the operating systems listed above. It may be altered or unavailable in subsequent versions. /// /// KP_KEYVAL = 30, /// KP_ADMIN_PIN = 31, /// KP_KEYEXCHANGE_PIN = 32, /// KP_SIGNATURE_PIN = 33, /// KP_PREHASH = 34, /// KP_ROUNDS = 35, /// KP_OAEP_PARAMS = 36, /// KP_CMS_KEY_INFO = 37, /// KP_CMS_DH_KEY_INFO = 38, /// KP_PUB_PARAMS = 39, /// /// Verifies the parameters of a Diffie-Hellman algorithm or DSA key. The pbData parameter is not used, and the value pointed to /// by pdwDataLen receives zero. /// This function returns a nonzero value if the key parameters are valid or zero otherwise. /// KP_VERIFY_PARAMS = 40, /// KP_HIGHEST_VERSION = 41, /// This value is not used. KP_GET_USE_COUNT = 42, /// KP_PIN_ID = 43, /// KP_PIN_INFO = 44, } /// The nature of the query. [PInvokeData("wincrypt.h", MSDNShortId = "c0b7c1c8-aa42-4d40-a7f7-99c0821c8977")] public enum ProvParam { /// Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR. PP_ADMIN_PIN = 0x1F, /// This constant is not used. PP_APPLI_CERT = 0x12, /// This constant is not used. PP_CHANGE_PASSWORD = 0x7, /// /// Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded. /// PP_CERTCHAIN = 0x9, /// /// The name of the current key container as a null-terminated CHAR string. This string is exactly the same as the one passed in /// the pszContainer parameter of the CryptAcquireContext function to specify the key container to use. The pszContainer /// parameter can be read to determine the name of the default key container. /// PP_CONTAINER = 0x6, /// /// Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. /// Windows XP: This parameter is not supported. /// PP_CRYPT_COUNT_KEY_USE = 0x29, /// /// A PROV_ENUMALGS structure that contains information about one algorithm supported by the CSP being queried. /// /// The first time this value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to /// retrieve the first element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag /// in the dwFlags parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has /// been reached. /// /// /// This function is not thread safe, and all of the available algorithms might not be enumerated if this function is used in a /// multithreaded context. /// /// PP_ENUMALGS = 0x1, /// /// A PROV_ENUMALGS_EX structure that contains information about one algorithm supported by the CSP being queried. The structure /// returned contains more information about the algorithm than the structure returned for PP_ENUMALGS. /// /// The first time this value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to /// retrieve the first element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag /// in the dwFlags parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has /// been reached. /// /// /// This function is not thread safe and all of the available algorithms might not be enumerated if this function is used in a /// multithreaded context. /// /// PP_ENUMALGS_EX = 0x16, /// /// The name of one of the key containers maintained by the CSP in the form of a null-terminated CHAR string. /// /// The first time this value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to /// retrieve the first element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag /// in the dwFlags parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has /// been reached. /// /// /// To enumerate key containers associated with a computer, first call CryptAcquireContext using the CRYPT_MACHINE_KEYSET flag, /// and then use the handle returned from CryptAcquireContext as the hProv parameter in the call to CryptGetProvParam. /// /// /// This function is not thread safe and all of the available algorithms might not be enumerated if this function is used in a /// multithreaded context. /// /// PP_ENUMCONTAINERS = 0x2, /// This constant is not used. PP_ENUMELECTROOTS = 0x1A, /// /// Indicates that the current CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function succeeds, /// the CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function fails with an NTE_BAD_TYPE error /// code, the CSP does not support the dwProtocols member. /// PP_ENUMEX_SIGNING_PROT = 0x28, /// This constant is not used. PP_ENUMMANDROOTS = 0x19, /// A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks. PP_IMPTYPE = 0x3, /// This query is not used. PP_KEY_TYPE_SUBTYPE = 0xA, /// /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. /// PP_KEYEXCHANGE_PIN = 0x20, /// /// Retrieves the security descriptor for the key storage container. The pbData parameter is the address of a /// SECURITY_DESCRIPTOR structure that receives the security descriptor for the key storage container. The security descriptor /// is returned in self-relative format. /// PP_KEYSET_SEC_DESCR = 0x8, /// /// Determines whether the hProv parameter is a computer key set. The pbData parameter must be a DWORD; the DWORD will be set to /// the CRYPT_MACHINE_KEYSET flag if that flag was passed to the CryptAcquireContext function. /// PP_KEYSET_TYPE = 0x1B, /// /// Returns information about the key specifier values that the CSP supports. Key specifier values are joined in a logical OR /// and returned in the pbData parameter of the call as a DWORD. For example, the Microsoft Base Cryptographic Provider version /// 1.0 returns a DWORD value of AT_SIGNATURE | AT_KEYEXCHANGE. /// PP_KEYSPEC = 0x27, /// Returns a DWORD value of CRYPT_SEC_DESCR. PP_KEYSTORAGE = 0x11, /// /// The number of bits for the increment length of AT_KEYEXCHANGE. This information is used with information returned in the /// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_KEYX_KEYSIZE_INC, the valid key lengths /// for AT_KEYEXCHANGE can be determined. These key lengths can then be used with CryptGenKey. For example if a CSP enumerates /// CALG_RSA_KEYX (AT_KEYEXCHANGE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment /// length as 64 bits, then valid key lengths are 512, 576, 640,… 1024. /// PP_KEYX_KEYSIZE_INC = 0x23, /// /// The name of the CSP in the form of a null-terminated CHAR string. This string is identical to the one passed in the /// pszProvider parameter of the CryptAcquireContext function to specify that the current CSP be used. /// PP_NAME = 0x4, /// A DWORD value that indicates the provider type of the CSP. PP_PROVTYPE = 0x10, /// /// Obtains the root certificate store for the smart card. This certificate store contains all of the root certificates that are /// stored on the smart card. /// /// The pbData parameter is the address of an HCERTSTORE variable that receives the handle of the certificate store. When this /// handle is no longer needed, the caller must close it by using the CertCloseStore function. /// /// Windows Server 2003 and Windows XP: This parameter is not supported. /// PP_ROOT_CERTSTORE = 0x2E, /// The size, in bits, of the session key. PP_SESSION_KEYSIZE = 0x14, /// Used with server gated cryptography. PP_SGC_INFO = 0x25, /// /// The number of bits for the increment length of AT_SIGNATURE. This information is used with information returned in the /// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_SIG_KEYSIZE_INC, the valid key lengths /// for AT_SIGNATURE can be determined. These key lengths can then be used with CryptGenKey. /// /// For example, if a CSP enumerates CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits and a maximum of 1024 /// bits, and returns the increment length as 64 bits, then valid key lengths are 512, 576, 640,… 1024. /// /// PP_SIG_KEYSIZE_INC = 0x22, /// /// Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. /// PP_SIGNATURE_PIN = 0x21, /// /// Obtains the identifier of the smart card. The pbData parameter is the address of a GUID structure that receives the /// identifier of the smart card. /// Windows Server 2003 and Windows XP: This parameter is not supported. /// PP_SMARTCARD_GUID = 0x2D, /// /// Obtains the name of the smart card reader. The pbData parameter is the address of an ANSI character array that receives a /// null-terminated ANSI string that contains the name of the smart card reader. The size of this buffer, contained in the /// variable pointed to by the pdwDataLen parameter, must include the NULL terminator. /// Windows Server 2003 and Windows XP: This parameter is not supported. /// PP_SMARTCARD_READER = 0x2B, /// PP_SMARTCARD_READER_ICON = 47, /// The size of the symmetric key. PP_SYM_KEYSIZE = 0x13, /// This query is not used. PP_UI_PROMPT = 0x15, /// /// The unique container name of the current key container in the form of a null-terminated CHAR string. For many CSPs, this /// name is the same name returned when the PP_CONTAINER value is used. The CryptAcquireContext function must work with this /// container name. /// PP_UNIQUE_CONTAINER = 0x24, /// /// Indicates whether a hardware random number generator (RNG) is supported. When PP_USE_HARDWARE_RNG is specified, the function /// succeeds and returns TRUE if a hardware RNG is supported. The function fails and returns FALSE if a hardware RNG is not /// supported. If a RNG is supported, PP_USE_HARDWARE_RNG can be set in CryptSetProvParam to indicate that the CSP must /// exclusively use the hardware RNG for this provider context. When PP_USE_HARDWARE_RNG is used, the pbData parameter must be /// NULL and dwFlags must be zero. /// None of the Microsoft CSPs currently support using a hardware RNG. /// PP_USE_HARDWARE_RNG = 0x26, /// /// Obtains the user certificate store for the smart card. This certificate store contains all of the user certificates that are /// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING /// encoding and should contain the CERT_KEY_PROV_INFO_PROP_ID property. /// /// The pbData parameter is the address of an HCERTSTORE variable that receives the handle of an in-memory certificate store. /// When this handle is no longer needed, the caller must close it by using the CertCloseStore function. /// /// Windows Server 2003 and Windows XP: This parameter is not supported. /// PP_USER_CERTSTORE = 0x2A, /// /// The version number of the CSP. The least significant byte contains the minor version number and the next most significant /// byte the major version number. Version 2.0 is represented as 0x00000200. To maintain backward compatibility with earlier /// versions of the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the provider names /// retain the "v1.0" designation in later versions. /// PP_VERSION = 0x5, } /// /// /// The CryptAcquireContext function is used to acquire a handle to a particular key container within a particular cryptographic /// service provider (CSP). This returned handle is used in calls to CryptoAPI functions that use the selected CSP. /// /// /// This function first attempts to find a CSP with the characteristics described in the dwProvType and pszProvider parameters. If /// the CSP is found, the function attempts to find a key container within the CSP that matches the name specified by the /// pszContainer parameter. To acquire the context and the key container of a private key associated with the public key of a /// certificate, use CryptAcquireCertificatePrivateKey. /// /// /// With the appropriate setting of dwFlags, this function can also create and destroy key containers and can provide access to a /// CSP with a temporary key container if access to a private key is not required. /// /// /// /// A pointer to a handle of a CSP. When you have finished using the CSP, release the handle by calling the CryptReleaseContext function. /// /// /// /// The key container name. This is a null-terminated string that identifies the key container to the CSP. This name is independent /// of the method used to store the keys. Some CSPs store their key containers internally (in hardware), some use the system /// registry, and others use the file system. In most cases, when dwFlags is set to CRYPT_VERIFYCONTEXT, pszContainer must be set to /// NULL. However, for hardware-based CSPs, such as a smart card CSP, can be access publically available information in the /// specfied container. /// /// For more information about the usage of the pszContainer parameter, see Remarks. /// /// /// A null-terminated string that contains the name of the CSP to be used. /// /// If this parameter is NULL, the user default provider is used. For more information, see Cryptographic Service Provider /// Contexts. For a list of available cryptographic providers, see Cryptographic Provider Names. /// /// /// An application can obtain the name of the CSP in use by using the CryptGetProvParam function to read the PP_NAME CSP value in /// the dwParam parameter. /// /// /// The default CSP can change between operating system releases. To ensure interoperability on different operating system /// platforms, the CSP should be explicitly set by using this parameter instead of using the default CSP. /// /// /// /// Specifies the type of provider to acquire. Defined provider types are discussed in Cryptographic Provider Types. /// /// /// Flag values. This parameter is usually set to zero, but some applications set one or more of the following flags. /// /// /// Value /// Meaning /// /// /// CRYPT_VERIFYCONTEXT /// /// This option is intended for applications that are using ephemeral keys, or applications that do not require access to persisted /// private keys, such as applications that perform only hashing, encryption, and digital signature verification. Only applications /// that create signatures or decrypt messages need access to a private key. In most cases, this flag should be set. For file-based /// CSPs, when this flag is set, the pszContainer parameter must be set to NULL. The application has no access to the persisted /// private keys of public/private key pairs. When this flag is set, temporary public/private key pairs can be created, but they are /// not persisted. For hardware-based CSPs, such as a smart card CSP, if the pszContainer parameter is NULL or blank, this flag /// implies that no access to any keys is required, and that no UI should be presented to the user. This form is used to connect to /// the CSP to query its capabilities but not to actually use its keys. If the pszContainer parameter is not NULL and not blank, /// then this flag implies that access to only the publicly available information within the specified container is required. The /// CSP should not ask for a PIN. Attempts to access private information (for example, the CryptSignHash function) will fail. When /// CryptAcquireContext is called, many CSPs require input from the owning user before granting access to the private keys in the /// key container. For example, the private keys can be encrypted, requiring a password from the user before they can be used. /// However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private keys is not required and the user interface can be bypassed. /// /// /// /// CRYPT_NEWKEYSET /// /// Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the default /// name is created. /// /// /// /// CRYPT_MACHINE_KEYSET /// /// By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are stored /// in the user's profile. A key container created without this flag by an administrator can be accessed only by the user creating /// the key container and a user with administration privileges. Windows XP: A key container created without this flag by an /// administrator can be accessed only by the user creating the key container and the local system account. A key container created /// without this flag by a user that is not an administrator can be accessed only by the user creating the key container and the /// local system account. The CRYPT_MACHINE_KEYSET flag can be combined with all of the other flags to indicate that the key /// container of interest is a computer key container and the CSP treats it as such. For Base Providers, this means that the keys /// are stored locally on the computer that created the key container. If a key container is to be a computer container, the /// CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the computer container. The key /// container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its creator and by a user with /// administrator privileges unless access rights to the container are granted using CryptSetProvParam. Windows XP: The key /// container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its creator and by the local system /// account unless access rights to the container are granted using CryptSetProvParam. The key container created with /// CRYPT_MACHINE_KEYSET by a user that is not an administrator can be accessed only by its creator and by the local system account /// unless access rights to the container are granted using CryptSetProvParam. The CRYPT_MACHINE_KEYSET flag is useful when the user /// is accessing from a service or user account that did not log on interactively. When key containers are created, most CSPs do not /// automatically create any public/private key pairs. These keys must be created as a separate step with the CryptGenKey function. /// /// /// /// CRYPT_DELETEKEYSET /// /// Delete the key container specified by pszContainer. If pszContainer is NULL, the key container with the default name is deleted. /// All key pairs in the key container are also destroyed. When this flag is set, the value returned in phProv is undefined, and /// thus, the CryptReleaseContext function need not be called afterward. /// /// /// /// CRYPT_SILENT /// /// The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to /// operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error. In addition, if calls are made to /// CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls fail /// and the CSP sets NTE_SILENT_CONTEXT. CRYPT_SILENT is intended for use with applications for which the UI cannot be displayed by /// the CSP. /// /// /// /// CRYPT_DEFAULT_CONTAINER_OPTIONAL /// /// Obtains a context for a smart card CSP that can be used for hashing and symmetric key operations but cannot be used for any /// operation that requires authentication to a smart card using a PIN. This type of context is most often used to perform /// operations on an empty smart card, such as setting the PIN by using CryptSetProvParam. This flag can only be used with smart /// card CSPs. Windows Server 2003 and Windows XP: This flag is not supported. /// /// /// /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes defined in Winerror.h follow. /// /// /// /// Return code/value /// Description /// /// /// ERROR_BUSY 107L /// Some CSPs set this error if the CRYPT_DELETEKEYSET flag value is set and another thread or process is using this key container. /// /// /// ERROR_FILE_NOT_FOUND 2L /// /// The profile of the user is not loaded and cannot be found. This happens when the application impersonates a user, for example, /// the IUSR_ComputerName account. /// /// /// /// ERROR_INVALID_PARAMETER 87L /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_NOT_ENOUGH_MEMORY 8L /// The operating system ran out of memory during the operation. /// /// /// NTE_BAD_FLAGS 0x80090009L /// The dwFlags parameter has a value that is not valid. /// /// /// NTE_BAD_KEY_STATE 0x8009000BL /// The user password has changed since the private keys were encrypted. /// /// /// NTE_BAD_KEYSET 0x80090016L /// /// The key container could not be opened. A common cause of this error is that the key container does not exist. To create a key /// container, call CryptAcquireContext using the CRYPT_NEWKEYSET flag. This error code can also indicate that access to an existing /// key container is denied. Access rights to the container can be granted by the key set creator by using CryptSetProvParam. /// /// /// /// NTE_BAD_KEYSET_PARAM 0x8009001FL /// The pszContainer or pszProvider parameter is set to a value that is not valid. /// /// /// NTE_BAD_PROV_TYPE 0x80090014L /// The value of the dwProvType parameter is out of range. All provider types must be from 1 through 999, inclusive. /// /// /// NTE_BAD_SIGNATURE 0x80090006L /// The provider DLL signature could not be verified. Either the DLL or the digital signature has been tampered with. /// /// /// NTE_EXISTS 0x8009000FL /// The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists. /// /// /// NTE_KEYSET_ENTRY_BAD 0x8009001AL /// The pszContainer key container was found but is corrupt. /// /// /// NTE_KEYSET_NOT_DEF 0x80090019L /// The requested provider does not exist. /// /// /// NTE_NO_MEMORY 0x8009000EL /// The CSP ran out of memory during the operation. /// /// /// NTE_PROV_DLL_NOT_FOUND 0x8009001EL /// The provider DLL file does not exist or is not on the current path. /// /// /// NTE_PROV_TYPE_ENTRY_BAD 0x80090018L /// /// The provider type specified by dwProvType is corrupt. This error can relate to either the user default CSP list or the computer /// default CSP list. /// /// /// /// NTE_PROV_TYPE_NO_MATCH 0x8009001BL /// /// The provider type specified by dwProvType does not match the provider type found. Note that this error can only occur when /// pszProvider specifies an actual CSP name. /// /// /// /// NTE_PROV_TYPE_NOT_DEF 0x80090017L /// No entry exists for the provider type specified by dwProvType. /// /// /// NTE_PROVIDER_DLL_FAIL 0x8009001DL /// The provider DLL file could not be loaded or failed to initialize. /// /// /// NTE_SIGNATURE_FILE_BAD 0x8009001CL /// An error occurred while loading the DLL file image, prior to verifying its signature. /// /// /// /// /// /// The pszContainer parameter specifies the name of the container that is used to hold the key. Each container can contain one key. /// If you specify the name of an existing container when creating keys, the new key will overwrite a previous one. /// /// /// The combination of the CSP name and the key container name uniquely identifies a single key on the system. If one application /// tries to modify a key container while another application is using it, unpredictable behavior may result. /// /// /// If you set the pszContainer parameter to NULL, the default key container name is used. When the Microsoft software CSPs /// are called in this manner, a new container is created each time the CryptAcquireContext function is called. However, /// different CSPs may behave differently in this regard. In particular, a CSP may have a single default container that is shared by /// all applications accessing the CSP. Therefore, applications must not use the default key container to store private keys. /// Instead, either prevent key storage by passing the CRYPT_VERIFYCONTEXT flag in the dwFlags parameter, or use an /// application-specific container that is unlikely to be used by another application. /// /// /// An application can obtain the name of the key container in use by using the CryptGetProvParam function to read the PP_CONTAINER value. /// /// /// For performance reasons, we recommend that you set the pszContainer parameter to NULL and the dwFlags parameter to /// CRYPT_VERIFYCONTEXT in all situations where you do not require a persisted key. In particular, consider setting the /// pszContainer parameter to NULL and the dwFlags parameter to CRYPT_VERIFYCONTEXT for the following scenarios: /// /// /// /// You are creating a hash. /// /// /// You are generating a symmetric key to encrypt or decrypt data. /// /// /// You are deriving a symmetric key from a hash to encrypt or decrypt data. /// /// /// /// You are verifying a signature. It is possible to import a public key from a PUBLICKEYBLOB or from a certificate by using /// CryptImportKey or CryptImportPublicKeyInfo. A context can be acquired by using the CRYPT_VERIFYCONTEXT flag if you only /// plan to import the public key. /// /// /// /// /// You plan to export a symmetric key, but not import it within the crypto context's lifetime. A context can be acquired by using /// the CRYPT_VERIFYCONTEXT flag if you only plan to import the public key for the last two scenarios. /// /// /// /// You are performing private key operations, but you are not using a persisted private key that is stored in a key container. /// /// /// /// If you plan to perform private key operations, the best way to acquire a context is to try to open the container. If this /// attempt fails with NTE_BAD_KEYSET, then create the container by using the CRYPT_NEWKEYSET flag. /// /// Examples /// /// The following example shows acquiring a cryptographic context and access to public/private key pairs in a key container. If the /// requested key container does not exist, it is created. /// /// /// For an example that includes the complete context for this example, see Example C Program: Creating a Key Container and /// Generating Keys. For additional examples, see Example C Program: Using CryptAcquireContext. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta BOOL CryptAcquireContextA( // HCRYPTPROV *phProv, LPCSTR szContainer, LPCSTR szProvider, DWORD dwProvType, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "57e13662-3189-4f8d-b90a-d1fbdc09b63c")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptAcquireContext(out SafeHCRYPTPROV phProv, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szContainer, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szProvider, uint dwProvType, CryptAcquireContextFlags dwFlags); /// /// The CryptContextAddRef function adds one to the reference count of an HCRYPTPROV cryptographic service provider (CSP) handle. /// This function should be used if the CSP handle is included as a member of any structure passed to another function. The /// CryptReleaseContext function should be called when the CSP handle is no longer needed. /// /// /// HCRYPTPROV handle for which the reference count is being incremented. This handle must have already been created using CryptAcquireContext. /// /// Reserved for future use and must be NULL. /// Reserved for future use and must be zero. /// /// If the function succeeds, the return value is nonzero (TRUE). /// /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. One possible error /// code is the following. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// /// /// /// This function increases the reference count on a HCRYPTPROV handle so that multiple calls to CryptReleaseContext are required to /// actually release the handle. /// /// Examples /// The following example increments the reference count on an acquired CSP handle. /// For another example that uses this function, see Example C Program: Using CryptAcquireContext. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptcontextaddref BOOL CryptContextAddRef( HCRYPTPROV // hProv, DWORD *pdwReserved, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "074666a7-369c-43bc-97d9-3bcc9703976b")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptContextAddRef(HCRYPTPROV hProv, IntPtr pdwReserved = default, uint dwFlags = 0); /// /// The CryptCreateHash function initiates the hashing of a stream of data. It creates and returns to the calling application a /// handle to a cryptographic service provider (CSP) hash object. This handle is used in subsequent calls to CryptHashData and /// CryptHashSessionKey to hash session keys and other streams of data. /// /// A handle to a CSP created by a call to CryptAcquireContext. /// /// An ALG_ID value that identifies the hash algorithm to use. /// Valid values for this parameter vary, depending on the CSP that is used. For a list of default algorithms, see Remarks. /// /// /// /// If the type of hash algorithm is a keyed hash, such as the Hash-Based Message Authentication Code (HMAC) or Message /// Authentication Code (MAC) algorithm, the key for the hash is passed in this parameter. For nonkeyed algorithms, this parameter /// must be set to zero. /// /// /// For keyed algorithms, the key must be to a block cipher key, such as RC2, that has a cipher mode of Cipher Block Chaining (CBC). /// /// /// /// The following flag value is defined. /// /// /// Value /// Meaning /// /// /// CRYPT_SECRETDIGEST 0x00000001 /// This flag is not used. /// /// /// /// /// The address to which the function copies a handle to the new hash object. When you have finished using the hash object, release /// the handle by calling the CryptDestroyHash function. /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// /// The error codes prefaced by NTE are generated by the particular CSP you are using. The following table shows some of the /// possible error codes. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// The operating system ran out of memory during the operation. /// /// /// NTE_BAD_ALGID /// The Algid parameter specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_KEY /// /// A keyed hash algorithm, such as CALG_MAC, is specified by Algid, and the hKey parameter is either zero or it specifies a key /// handle that is not valid. This error code is also returned if the key is to a stream cipher or if the cipher mode is anything /// other than CBC. /// /// /// /// NTE_NO_MEMORY /// The CSP ran out of memory during the operation. /// /// /// /// /// For a list of Microsoft service providers and the algorithms they implement, see Microsoft Cryptographic Service Providers. /// /// The computation of the actual hash is done with the CryptHashData and CryptHashSessionKey functions. These require a handle to /// the hash object. After all the data has been added to the hash object, any of the following operations can be performed: /// /// /// /// The hash value can be retrieved by using CryptGetHashParam. /// /// /// A session key can be derived by using CryptDeriveKey. /// /// /// The hash can be signed by using CryptSignHash. /// /// /// A signature can be verified by using CryptVerifySignature. /// /// /// After one of the functions from this list has been called, CryptHashData and CryptHashSessionKey cannot be called. /// Examples /// /// The following example shows initiating the hashing of a stream of data. It creates and returns to the calling application a /// handle to a hash object. This handle is used in subsequent calls to CryptHashData and CryptHashSessionKey to hash any stream of /// data. For an example that includes the complete context for this example, see Example C Program: Creating and Hashing a Session /// Key. For another example that uses this function, see Example C Program: Signing a Hash and Verifying the Hash Signature. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptcreatehash BOOL CryptCreateHash( HCRYPTPROV hProv, // ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "05e3db57-8d83-48e2-8590-68039ea27253")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, [Optional] uint dwFlags, out SafeHCRYPTHASH phHash); /// /// The CryptDecrypt function decrypts data previously encrypted by using the CryptEncrypt function. /// /// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to /// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode. /// /// /// /// /// A handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or /// CryptImportKey function. /// /// This key specifies the decryption algorithm to be used. /// /// /// /// A handle to a hash object. If data is to be decrypted and hashed simultaneously, a handle to a hash object is passed in this /// parameter. The hash value is updated with the decrypted plaintext. This option is useful when simultaneously decrypting and /// verifying a signature. /// /// /// Before calling CryptDecrypt, the application must obtain a handle to the hash object by calling the CryptCreateHash /// function. After the decryption is complete, the hash value can be obtained by using the CryptGetHashParam function, it can also /// be signed by using the CryptSignHash function, or it can be used to verify a digital signature by using the CryptVerifySignature function. /// /// If no hash is to be done, this parameter must be zero. /// /// /// A Boolean value that specifies whether this is the last section in a series being decrypted. This value is TRUE if this /// is the last or only block. If this is not the last block, this value is FALSE. For more information, see Remarks. /// /// /// The following flag values are defined. /// /// /// Value /// Meaning /// /// /// CRYPT_OAEP 0x00000040 /// /// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag. /// /// /// /// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 0x00000020 /// /// Perform the decryption on the BLOB without checking the padding. This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_OAEP flag. /// /// /// /// /// /// /// A pointer to a buffer that contains the data to be decrypted. After the decryption has been performed, the plaintext is placed /// back into this same buffer. /// /// The number of encrypted bytes in this buffer is specified by pdwDataLen. /// /// /// /// A pointer to a DWORD value that indicates the length of the pbData buffer. Before calling this function, the calling /// application sets the DWORD value to the number of bytes to be decrypted. Upon return, the DWORD value contains the /// number of bytes of the decrypted plaintext. /// /// /// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to /// be decrypted and the Final parameter is TRUE. /// /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Value /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The hKey session key specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_DATA /// /// The data to be decrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified /// by pdwDataLen must be a multiple of the block size. This error can also be returned when the padding is found to be not valid. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hHash parameter contains a handle that is not valid. /// /// /// NTE_BAD_KEY /// The hKey parameter does not contain a valid handle to a key. /// /// /// NTE_BAD_LEN /// The size of the output buffer is too small to hold the generated plaintext. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the key was created cannot be found. /// /// /// NTE_DOUBLE_ENCRYPT /// The application attempted to decrypt the same data twice. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// /// /// /// If a large amount of data is to be decrypted, it can be done in sections by calling CryptDecrypt repeatedly. The Final /// parameter must be set to TRUE only on the last call to CryptDecrypt, so that the decryption engine can properly /// finish the decryption process. The following extra actions are performed when Final is TRUE: /// /// /// /// /// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. To find the block size of a /// cipher, use CryptGetKeyParam to get the KP_BLOCKLEN value of the key. /// /// /// /// /// If the cipher is operating in a chaining mode, the next CryptDecrypt operation resets the cipher's feedback register to /// the KP_IV value of the key. /// /// /// /// If the cipher is a stream cipher, the next CryptDecrypt call resets the cipher to its initial state. /// /// /// /// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to /// TRUE. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of /// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and /// passing the duplicate key to the CryptDecrypt function. This causes the KP_IV of the original key to be placed in the /// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback /// register of the key will be changed. The following pseudocode shows how this can be done. /// /// /// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private /// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of ciphertext data to be /// decrypted must be the same length as the modulus of the RSA key used to decrypt the data. If the ciphertext has zeros in the /// most significant bytes, these bytes must be included in the input data buffer and in the input buffer length. The ciphertext /// must be in little-endian format. /// /// Examples /// For an example that uses this function, see Example C Program: Decrypting a File. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecrypt BOOL CryptDecrypt( HCRYPTKEY hKey, // HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "7c3d2838-6fd1-4f6c-9586-8b94b459a31a")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptDecryptFlags dwFlags, [In, Out] IntPtr pbData, ref uint pdwDataLen); /// /// The CryptDecrypt function decrypts data previously encrypted by using the CryptEncrypt function. /// /// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to /// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode. /// /// /// /// /// A handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or /// CryptImportKey function. /// /// This key specifies the decryption algorithm to be used. /// /// /// /// A handle to a hash object. If data is to be decrypted and hashed simultaneously, a handle to a hash object is passed in this /// parameter. The hash value is updated with the decrypted plaintext. This option is useful when simultaneously decrypting and /// verifying a signature. /// /// /// Before calling CryptDecrypt, the application must obtain a handle to the hash object by calling the CryptCreateHash /// function. After the decryption is complete, the hash value can be obtained by using the CryptGetHashParam function, it can also /// be signed by using the CryptSignHash function, or it can be used to verify a digital signature by using the CryptVerifySignature function. /// /// If no hash is to be done, this parameter must be zero. /// /// /// A Boolean value that specifies whether this is the last section in a series being decrypted. This value is TRUE if this /// is the last or only block. If this is not the last block, this value is FALSE. For more information, see Remarks. /// /// /// The following flag values are defined. /// /// /// Value /// Meaning /// /// /// CRYPT_OAEP 0x00000040 /// /// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag. /// /// /// /// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 0x00000020 /// /// Perform the decryption on the BLOB without checking the padding. This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_OAEP flag. /// /// /// /// /// /// /// A pointer to a buffer that contains the data to be decrypted. After the decryption has been performed, the plaintext is placed /// back into this same buffer. /// /// The number of encrypted bytes in this buffer is specified by pdwDataLen. /// /// /// /// A pointer to a DWORD value that indicates the length of the pbData buffer. Before calling this function, the calling /// application sets the DWORD value to the number of bytes to be decrypted. Upon return, the DWORD value contains the /// number of bytes of the decrypted plaintext. /// /// /// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to /// be decrypted and the Final parameter is TRUE. /// /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Value /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The hKey session key specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_DATA /// /// The data to be decrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified /// by pdwDataLen must be a multiple of the block size. This error can also be returned when the padding is found to be not valid. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hHash parameter contains a handle that is not valid. /// /// /// NTE_BAD_KEY /// The hKey parameter does not contain a valid handle to a key. /// /// /// NTE_BAD_LEN /// The size of the output buffer is too small to hold the generated plaintext. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the key was created cannot be found. /// /// /// NTE_DOUBLE_ENCRYPT /// The application attempted to decrypt the same data twice. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// /// /// /// If a large amount of data is to be decrypted, it can be done in sections by calling CryptDecrypt repeatedly. The Final /// parameter must be set to TRUE only on the last call to CryptDecrypt, so that the decryption engine can properly /// finish the decryption process. The following extra actions are performed when Final is TRUE: /// /// /// /// /// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. To find the block size of a /// cipher, use CryptGetKeyParam to get the KP_BLOCKLEN value of the key. /// /// /// /// /// If the cipher is operating in a chaining mode, the next CryptDecrypt operation resets the cipher's feedback register to /// the KP_IV value of the key. /// /// /// /// If the cipher is a stream cipher, the next CryptDecrypt call resets the cipher to its initial state. /// /// /// /// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to /// TRUE. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of /// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and /// passing the duplicate key to the CryptDecrypt function. This causes the KP_IV of the original key to be placed in the /// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback /// register of the key will be changed. The following pseudocode shows how this can be done. /// /// /// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private /// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of ciphertext data to be /// decrypted must be the same length as the modulus of the RSA key used to decrypt the data. If the ciphertext has zeros in the /// most significant bytes, these bytes must be included in the input data buffer and in the input buffer length. The ciphertext /// must be in little-endian format. /// /// Examples /// For an example that uses this function, see Example C Program: Decrypting a File. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecrypt BOOL CryptDecrypt( HCRYPTKEY hKey, // HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "7c3d2838-6fd1-4f6c-9586-8b94b459a31a")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptDecryptFlags dwFlags, [In, Out] byte[] pbData, ref int pdwDataLen); /// /// /// The CryptDeriveKey function generates cryptographic session keys derived from a base data value. This function guarantees that /// when the same cryptographic service provider (CSP) and algorithms are used, the keys generated from the same base data are /// identical. The base data can be a password or any other user data. /// /// /// This function is the same as CryptGenKey, except that the generated session keys are derived from base data instead of being /// random. CryptDeriveKey can only be used to generate session keys. It cannot generate public/private key pairs. /// /// /// A handle to the session key is returned in the phKey parameter. This handle can be used with any CryptoAPI function that /// requires a key handle. /// /// /// A HCRYPTPROV handle of a CSP created by a call to CryptAcquireContext. /// /// /// An ALG_ID structure that identifies the symmetric encryption algorithm for which the key is to be generated. The algorithms /// available will most likely be different for each CSP. For more information about which algorithm identifier is used by the /// different providers for the key specs AT_KEYEXCHANGE and AT_SIGNATURE, see ALG_ID. /// /// /// For more information about ALG_ID values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms. /// For more information about ALG_ID values to use with the Microsoft Strong Cryptographic Provider or the Microsoft /// Enhanced Cryptographic Provider, see Enhanced Provider Algorithms. /// /// /// /// A handle to a hash object that has been fed the exact base data. /// /// To obtain this handle, an application must first create a hash object with CryptCreateHash and then add the base data to the /// hash object with CryptHashData. This process is described in detail in Hashes and Digital Signatures. /// /// /// /// Specifies the type of key generated. /// /// The sizes of a session key can be set when the key is generated. The key size, representing the length of the key modulus in /// bits, is set with the upper 16 bits of this parameter. Thus, if a 128-bit RC4 session key is to be generated, the value /// 0x00800000 is combined with any other dwFlags predefined value with a bitwise- OR operation. Due to changing export /// control restrictions, the default CSP and default key length may change between operating system releases. It is important that /// both the encryption and decryption use the same CSP and that the key length be explicitly set using the dwFlags parameter to /// ensure interoperability on different operating system platforms. /// /// /// The lower 16 bits of this parameter can be zero or you can specify one or more of the following flags by using the bitwise- /// OR operator to combine them. /// /// /// /// Value /// Meaning /// /// /// CRYPT_CREATE_SALT /// /// Typically, when a session key is made from a hash value, there are a number of leftover bits. For example, if the hash value is /// 128 bits and the session key is 40 bits, there will be 88 bits left over. If this flag is set, then the key is assigned a salt /// value based on the unused hash value bits. You can retrieve this salt value by using the CryptGetKeyParam function with the /// dwParam parameter set to KP_SALT. If this flag is not set, then the key is given a salt value of zero. When keys with nonzero /// salt values are exported (by using CryptExportKey), the salt value must also be obtained and kept with the key BLOB. /// /// /// /// CRYPT_EXPORTABLE /// /// If this flag is set, the session key can be transferred out of the CSP into a key BLOB through the CryptExportKey function. /// Because keys generally must be exportable, this flag should usually be set. If this flag is not set, then the session key is not /// exportable. This means the key is available only within the current session and only the application that created it is able to /// use it. This flag does not apply to public/private key pairs. /// /// /// /// CRYPT_NO_SALT /// /// This flag specifies that a no salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. /// /// /// /// CRYPT_UPDATE_KEY /// /// Some CSPs use session keys that are derived from multiple hash values. When this is the case, CryptDeriveKey must be called /// multiple times. If this flag is set, a new session key is not generated. Instead, the key specified by phKey is modified. The /// precise behavior of this flag is dependent on the type of key being generated and on the particular CSP being used. Microsoft /// cryptographic service providers ignore this flag. /// /// /// /// CRYPT_SERVER 1024 (0x400) /// /// This flag is used only with Schannel providers. If this flag is set, the key to be generated is a server-write key; otherwise, /// it is a client-write key. /// /// /// /// /// /// A pointer to a HCRYPTKEY variable to receive the address of the handle of the newly generated key. When you have finished using /// the key, release the handle by calling the CryptDestroyKey function. /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the /// following table. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The Algid parameter specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter contains a value that is not valid. /// /// /// NTE_BAD_HASH /// The hBaseData parameter does not contain a valid handle to a hash object. /// /// /// NTE_BAD_HASH_STATE /// An attempt was made to add data to a hash object that is already marked "finished." /// /// /// NTE_BAD_UID /// The hProv parameter does not contain a valid context handle. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// NTE_SILENT_CONTEXT /// The provider could not perform the action because the context was acquired as silent. /// /// /// /// /// /// When keys are generated for symmetric block ciphers, the key by default is set up in cipher block chaining (CBC) mode with an /// initialization vector of zero. This cipher mode provides a good default method for bulk-encrypting data. To change these /// parameters, use the CryptSetKeyParam function. /// /// /// The CryptDeriveKey function completes the hash. After CryptDeriveKey has been called, no more data can be added to /// the hash. Additional calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash, /// CryptDestroyHash must be called to destroy the hash object. /// /// To choose an appropriate key length, the following methods are recommended. /// /// /// /// To enumerate the algorithms that the CSP supports and to get maximum and minimum key lengths for each algorithm, call /// CryptGetProvParam with PP_ENUMALGS_EX. /// /// /// /// /// Use the minimum and maximum lengths to choose an appropriate key length. It is not always advisable to choose the maximum length /// because this can lead to performance issues. /// /// /// /// After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length. /// /// /// /// Let n be the required derived key length, in bytes. The derived key is the first n bytes of the hash value after /// the hash computation has been completed by CryptDeriveKey. If the hash is not a member of the SHA-2 family and the /// required key is for either 3DES or AES, the key is derived as follows: /// /// /// /// /// Form a 64-byte buffer by repeating the constant 0x36 64 times. Let k be the length of the hash value that is /// represented by the input parameter hBaseData. Set the first k bytes of the buffer to the result of an XOR /// operation of the first k bytes of the buffer with the hash value that is represented by the input parameter hBaseData. /// /// /// /// /// Form a 64-byte buffer by repeating the constant 0x5C 64 times. Set the first k bytes of the buffer to the result /// of an XOR operation of the first k bytes of the buffer with the hash value that is represented by the input /// parameter hBaseData. /// /// /// /// /// Hash the result of step 1 by using the same hash algorithm as that used to compute the hash value that is represented by the /// hBaseData parameter. /// /// /// /// /// Hash the result of step 2 by using the same hash algorithm as that used to compute the hash value that is represented by the /// hBaseData parameter. /// /// /// /// Concatenate the result of step 3 with the result of step 4. /// /// /// Use the first n bytes of the result of step 5 as the derived key. /// /// /// /// The default RSA Full Cryptographic Service Provider is the Microsoft RSA Strong Cryptographic Provider. The default DSS /// Signature Diffie-Hellman Cryptographic Service Provider is the Microsoft Enhanced DSS Diffie-Hellman Cryptographic Provider. /// Each of these CSPs has a default 128-bit symmetric key length for RC2 and RC4. /// /// The following table lists minimum, default, and maximum key lengths for session key by algorithm and provider. /// /// /// Provider /// Algorithms /// Minimum key length /// Default key length /// Maximum key length /// /// /// MS Base /// RC4 and RC2 /// 40 /// 40 /// 56 /// /// /// MS Base /// DES /// 56 /// 56 /// 56 /// /// /// MS Enhanced /// RC4 and RC2 /// 40 /// 128 /// 128 /// /// /// MS Enhanced /// DES /// 56 /// 56 /// 56 /// /// /// MS Enhanced /// 3DES 112 /// 112 /// 112 /// 112 /// /// /// MS Enhanced /// 3DES /// 168 /// 168 /// 168 /// /// /// MS Strong /// RC4 and RC2 /// 40 /// 128 /// 128 /// /// /// MS Strong /// DES /// 56 /// 56 /// 56 /// /// /// MS Strong /// 3DES 112 /// 112 /// 112 /// 112 /// /// /// MS Strong /// 3DES /// 168 /// 168 /// 168 /// /// /// DSS/DH Base /// RC4 and RC2 /// 40 /// 40 /// 56 /// /// /// DSS/DH Base /// Cylink MEK /// 40 /// 40 /// 40 /// /// /// DSS/DH Base /// DES /// 56 /// 56 /// 56 /// /// /// DSS/DH Enh /// RC4 and RC2 /// 40 /// 128 /// 128 /// /// /// DSS/DH Enh /// Cylink MEK /// 40 /// 40 /// 40 /// /// /// DSS/DH Enh /// DES /// 56 /// 56 /// 56 /// /// /// DSS/DH Enh /// 3DES 112 /// 112 /// 112 /// 112 /// /// /// DSS/DH Enh /// 3DES /// 168 /// 168 /// 168 /// /// /// Examples /// For an example that uses this function, see Example C Program: Deriving a Session Key from a Password. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptderivekey BOOL CryptDeriveKey( HCRYPTPROV hProv, // ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "b031e3b4-0102-400e-96db-019d31402adc")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, CryptGenKeyFlags dwFlags, out SafeHCRYPTKEY phKey); /// /// The CryptDestroyHash function destroys the hash object referenced by the hHash parameter. After a hash object has been /// destroyed, it can no longer be used. /// To help ensure security, we recommend that hash objects be destroyed after they have been used. /// /// The handle of the hash object to be destroyed. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular cryptographic service provider (CSP) you are using. Some /// possible error codes follow. /// /// /// /// Return code /// Description /// /// /// ERROR_BUSY /// The hash object specified by hHash is currently being used and cannot be destroyed. /// /// /// ERROR_INVALID_HANDLE /// The hHash parameter specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// The hHash parameter contains a value that is not valid. /// /// /// NTE_BAD_ALGID /// The hHash handle specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_HASH /// The hash object specified by the hHash parameter is not valid. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hash object was created cannot be found. /// /// /// /// /// /// When a hash object is destroyed, many CSPs overwrite the memory in the CSP where the hash object was held. The CSP memory is /// then freed. /// /// There should be a one-to-one correspondence between calls to CryptCreateHash and CryptDestroyHash. /// /// All hash objects that have been created by using a specific CSP must be destroyed before that CSP handle is released with the /// CryptReleaseContext function. /// /// Examples /// For an example that uses the CryptDestroyHash function, see Example C Program: Creating and Hashing a Session Key. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdestroyhash BOOL CryptDestroyHash( HCRYPTHASH hHash ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "0a4d6086-5c4c-4e1e-9ab9-b35ee49ffcae")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptDestroyHash(HCRYPTHASH hHash); /// /// The CryptDestroyKey function releases the handle referenced by the hKey parameter. After a key handle has been released, it is /// no longer valid and cannot be used again. /// /// If the handle refers to a session key, or to a public key that has been imported into the cryptographic service provider (CSP) /// through CryptImportKey, this function destroys the key and frees the memory that the key used. Many CSPs overwrite the memory /// where the key was held before freeing it. However, the underlying public/private key pair is not destroyed by this function. /// Only the handle is destroyed. /// /// /// The handle of the key to be destroyed. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the /// following table. /// /// /// /// Return code /// Description /// /// /// ERROR_BUSY /// The key object specified by hKey is currently being used and cannot be destroyed. /// /// /// ERROR_INVALID_HANDLE /// The hKey parameter specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// The hKey parameter contains a value that is not valid. /// /// /// NTE_BAD_KEY /// The hKey parameter does not contain a valid handle to a key. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the key was created cannot be found. /// /// /// /// /// /// Keys take up both operating system's memory space and the CSP's memory space. Some CSPs are implemented in hardware with limited /// memory resources. Applications must destroy all keys with the CryptDestroyKey function when they are finished with them. /// /// /// All key handles that have been created or imported by using a specific CSP must be destroyed before that CSP handle is released /// with the CryptReleaseContext function. /// /// Examples /// For an example that uses the CryptDestroyKey function, see Example C Program: Creating and Hashing a Session Key. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdestroykey BOOL CryptDestroyKey( HCRYPTKEY hKey ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "ed5d8047-c9fd-4765-915f-a6a014004b30")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptDestroyKey(HCRYPTKEY hKey); /// /// /// The CryptDuplicateHash function makes an exact copy of a hash to the point when the duplication is done. The duplicate /// hash includes the state of the hash. /// /// /// A hash can be created in a piece-by-piece way. The CryptDuplicateHash function can be used to create separate hashes of /// two different contents that begin with the same content. /// /// /// Handle of the hash to be duplicated. /// Reserved for future use and must be zero. /// Reserved for future use and must be zero. /// /// Address of the handle of the duplicated hash. When you have finished using the hash, release the handle by calling the /// CryptDestroyHash function. /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// /// The error code prefaced by "NTE" is generated by the particular cryptographic service provider (CSP) that you are using. Some /// possible error codes follow. /// /// /// /// Return code /// Description /// /// /// ERROR_CALL_NOT_IMPLEMENTED /// /// Because this is a new function, existing CSPs cannot implement it. This error is returned if the CSP does not support this function. /// /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_HASH /// A handle to the original hash is not valid. /// /// /// /// /// /// CryptDuplicateHash makes a copy of a hash and the exact state of the hash. This function might be used if a calling /// application needed to generate two hashes but both hashes had to start with some common data hashed. For example, a hash might /// be created, the common data hashed, a duplicate made with the CryptDuplicateHash function, and then the data unique to /// each hash would be added. /// /// /// The CryptDestroyHash function must be called to destroy any hashes that are created with CryptDuplicateHash. Destroying /// the original hash does not cause the duplicate hash to be destroyed. After a duplicate hash is made, it is separate from the /// original hash. There is no shared state between the two hashes. /// /// Examples /// /// The following example shows making an exact copy of a hash. For an example that includes the complete context for this example, /// see Example C Program: Duplicating a Hash. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptduplicatehash BOOL CryptDuplicateHash( HCRYPTHASH // hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "527fce4d-8d42-437b-9692-42583092efbb")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptDuplicateHash(HCRYPTHASH hHash, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out SafeHCRYPTHASH phHash); /// The CryptDuplicateKey function makes an exact copy of a key and the state of the key. /// A handle to the key to be duplicated. /// Reserved for future use and must be NULL. /// Reserved for future use and must be zero. /// /// Address of the handle to the duplicated key. When you have finished using the key, release the handle by calling the /// CryptDestroyKey function. /// /// /// If the function succeeds, the return value is nonzero (TRUE). /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. /// /// The error code prefaced by "NTE" is generated by the particular CSP being used. Some possible error codes are listed in the /// following table. /// /// /// /// Return code /// Description /// /// /// ERROR_CALL_NOT_IMPLEMENTED /// /// Because this is a new function, existing CSPs might not implement it. This error is returned if the CSP does not support this function. /// /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_KEY /// A handle to the original key is not valid. /// /// /// /// /// /// CryptDuplicateKey makes a copy of a key and the exact state of the key. One scenario when this function can be used is /// when an application needs to encrypt two separate messages with the same key but with different salt values. The original key is /// generated and then a duplicate key is made by using the CryptDuplicateKey function. The different salt values are then /// set on the original and duplicate keys with separate calls to the CryptSetKeyParam function. /// /// /// CryptDestroyKey must be called to destroy any keys that are created by using CryptDuplicateKey. Destroying the original /// key does not cause the duplicate key to be destroyed. After a duplicate key is made, it is separate from the original key. There /// is no shared state between the two keys. /// /// Examples /// /// The following example shows the creation of a session key that is a duplicate of an existing session key. For an example that /// includes the complete context for this example, see Example C Program: Duplicating a Session Key. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptduplicatekey BOOL CryptDuplicateKey( HCRYPTKEY hKey, // DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "c5658008-7c92-4877-871a-a764884efd79")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptDuplicateKey(HCRYPTKEY hKey, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out SafeHCRYPTKEY phKey); /// /// /// The CryptEncrypt function encrypts data. The algorithm used to encrypt the data is designated by the key held by the CSP module /// and is referenced by the hKey parameter. /// /// /// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to /// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode. /// /// /// Important The CryptEncrypt function is not guaranteed to be thread safe and may return incorrect results if /// invoked simultaneously by multiple callers. /// /// /// /// /// A handle to the encryption key. An application obtains this handle by using either the CryptGenKey or the CryptImportKey function. /// /// The key specifies the encryption algorithm used. /// /// /// /// A handle to a hash object. If data is to be hashed and encrypted simultaneously, a handle to a hash object can be passed in the /// hHash parameter. The hash value is updated with the plaintext passed in. This option is useful when generating signed and /// encrypted text. /// /// /// Before calling CryptEncrypt, the application must obtain a handle to the hash object by calling the CryptCreateHash /// function. After the encryption is complete, the hash value can be obtained by using the CryptGetHashParam function, or the hash /// can be signed by using the CryptSignHash function. /// /// If no hash is to be done, this parameter must be NULL. /// /// /// A Boolean value that specifies whether this is the last section in a series being encrypted. Final is set to TRUE for the /// last or only block and to FALSE if there are more blocks to be encrypted. For more information, see Remarks. /// /// /// The following dwFlags value is defined but reserved for future use. /// /// /// Value /// Meaning /// /// /// CRYPT_OAEP /// /// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. /// /// /// /// /// /// /// A pointer to a buffer that contains the plaintext to be encrypted. The plaintext in this buffer is overwritten with the /// ciphertext created by this function. /// /// /// The pdwDataLen parameter points to a variable that contains the length, in bytes, of the plaintext. The dwBufLen parameter /// contains the total size, in bytes, of this buffer. /// /// /// If this parameter contains NULL, this function will calculate the required size for the ciphertext and place that in the /// value pointed to by the pdwDataLen parameter. /// /// /// /// /// A pointer to a DWORD value that , on entry, contains the length, in bytes, of the plaintext in the pbData buffer. On /// exit, this DWORD contains the length, in bytes, of the ciphertext written to the pbData buffer. /// /// /// If the buffer allocated for pbData is not large enough to hold the encrypted data, GetLastError returns ERROR_MORE_DATA /// and stores the required buffer size, in bytes, in the DWORD value pointed to by pdwDataLen. /// /// /// If pbData is NULL, no error is returned, and the function stores the size of the encrypted data, in bytes, in the /// DWORD value pointed to by pdwDataLen. This allows an application to determine the correct buffer size. /// /// /// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to /// be encrypted and the Final parameter is TRUE. /// /// /// /// Specifies the total size, in bytes, of the input pbData buffer. /// /// Note that, depending on the algorithm used, the encrypted text can be larger than the original plaintext. In this case, the /// pbData buffer needs to be large enough to contain the encrypted text and any padding. /// /// /// As a rule, if a stream cipher is used, the ciphertext is the same size as the plaintext. If a block cipher is used, the /// ciphertext is up to a block length larger than the plaintext. /// /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Value /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The hKey session key specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_DATA /// /// The data to be encrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified /// by pdwDataLen must be a multiple of the block size. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hHash parameter contains a handle that is not valid. /// /// /// NTE_BAD_HASH_STATE /// An attempt was made to add data to a hash object that is already marked "finished." /// /// /// NTE_BAD_KEY /// The hKey parameter does not contain a valid handle to a key. /// /// /// NTE_BAD_LEN /// The size of the output buffer is too small to hold the generated ciphertext. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the key was created cannot be found. /// /// /// NTE_DOUBLE_ENCRYPT /// The application attempted to encrypt the same data twice. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// NTE_NO_MEMORY /// The CSP ran out of memory during the operation. /// /// /// /// /// /// If a large amount of data is to be encrypted, it can be done in sections by calling CryptEncrypt repeatedly. The Final /// parameter must be set to TRUE on the last call to CryptEncrypt, so that the encryption engine can properly finish /// the encryption process. The following extra actions are performed when Final is TRUE: /// /// /// /// /// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. If the data length equals /// the block size of the cipher, one additional block of padding is appended to the data. To find the block size of a cipher, use /// CryptGetKeyParam to get the KP_BLOCKLEN value of the key. /// /// /// /// /// If the cipher is operating in a chaining mode, the next CryptEncrypt operation resets the cipher's feedback register to /// the KP_IV value of the key. /// /// /// /// If the cipher is a stream cipher, the next CryptEncrypt resets the cipher to its initial state. /// /// /// /// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to /// TRUE. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of /// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and /// passing the duplicate key to the CryptEncrypt function. This causes the KP_IV of the original key to be placed in the /// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback /// register of the key will be changed. The following pseudocode shows how this can be done. /// /// /// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private /// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of plaintext data that can be /// encrypted with a call to CryptEncrypt with an RSA key is the length of the key modulus minus eleven bytes. The eleven /// bytes is the chosen minimum for PKCS #1 padding. The ciphertext is returned in little-endian format. /// /// Examples /// For examples that use this function, see Example C Program: Encrypting a File and Example C Program: Decrypting a File. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptencrypt BOOL CryptEncrypt( HCRYPTKEY hKey, // HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "697c4960-552b-4c3a-95cf-4632af56945b")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptEncryptFlags dwFlags, [In, Out] IntPtr pbData, ref uint pdwDataLen, uint dwBufLen); /// /// /// The CryptEncrypt function encrypts data. The algorithm used to encrypt the data is designated by the key held by the CSP module /// and is referenced by the hKey parameter. /// /// /// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to /// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode. /// /// /// Important The CryptEncrypt function is not guaranteed to be thread safe and may return incorrect results if /// invoked simultaneously by multiple callers. /// /// /// /// /// A handle to the encryption key. An application obtains this handle by using either the CryptGenKey or the CryptImportKey function. /// /// The key specifies the encryption algorithm used. /// /// /// /// A handle to a hash object. If data is to be hashed and encrypted simultaneously, a handle to a hash object can be passed in the /// hHash parameter. The hash value is updated with the plaintext passed in. This option is useful when generating signed and /// encrypted text. /// /// /// Before calling CryptEncrypt, the application must obtain a handle to the hash object by calling the CryptCreateHash /// function. After the encryption is complete, the hash value can be obtained by using the CryptGetHashParam function, or the hash /// can be signed by using the CryptSignHash function. /// /// If no hash is to be done, this parameter must be NULL. /// /// /// A Boolean value that specifies whether this is the last section in a series being encrypted. Final is set to TRUE for the /// last or only block and to FALSE if there are more blocks to be encrypted. For more information, see Remarks. /// /// /// The following dwFlags value is defined but reserved for future use. /// /// /// Value /// Meaning /// /// /// CRYPT_OAEP /// /// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced /// Cryptographic Provider with RSA encryption/decryption. /// /// /// /// /// /// /// A pointer to a buffer that contains the plaintext to be encrypted. The plaintext in this buffer is overwritten with the /// ciphertext created by this function. /// /// /// The pdwDataLen parameter points to a variable that contains the length, in bytes, of the plaintext. The dwBufLen parameter /// contains the total size, in bytes, of this buffer. /// /// /// If this parameter contains NULL, this function will calculate the required size for the ciphertext and place that in the /// value pointed to by the pdwDataLen parameter. /// /// /// /// /// A pointer to a DWORD value that , on entry, contains the length, in bytes, of the plaintext in the pbData buffer. On /// exit, this DWORD contains the length, in bytes, of the ciphertext written to the pbData buffer. /// /// /// If the buffer allocated for pbData is not large enough to hold the encrypted data, GetLastError returns ERROR_MORE_DATA /// and stores the required buffer size, in bytes, in the DWORD value pointed to by pdwDataLen. /// /// /// If pbData is NULL, no error is returned, and the function stores the size of the encrypted data, in bytes, in the /// DWORD value pointed to by pdwDataLen. This allows an application to determine the correct buffer size. /// /// /// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to /// be encrypted and the Final parameter is TRUE. /// /// /// /// Specifies the total size, in bytes, of the input pbData buffer. /// /// Note that, depending on the algorithm used, the encrypted text can be larger than the original plaintext. In this case, the /// pbData buffer needs to be large enough to contain the encrypted text and any padding. /// /// /// As a rule, if a stream cipher is used, the ciphertext is the same size as the plaintext. If a block cipher is used, the /// ciphertext is up to a block length larger than the plaintext. /// /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Value /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The hKey session key specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_DATA /// /// The data to be encrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified /// by pdwDataLen must be a multiple of the block size. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hHash parameter contains a handle that is not valid. /// /// /// NTE_BAD_HASH_STATE /// An attempt was made to add data to a hash object that is already marked "finished." /// /// /// NTE_BAD_KEY /// The hKey parameter does not contain a valid handle to a key. /// /// /// NTE_BAD_LEN /// The size of the output buffer is too small to hold the generated ciphertext. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the key was created cannot be found. /// /// /// NTE_DOUBLE_ENCRYPT /// The application attempted to encrypt the same data twice. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// NTE_NO_MEMORY /// The CSP ran out of memory during the operation. /// /// /// /// /// /// If a large amount of data is to be encrypted, it can be done in sections by calling CryptEncrypt repeatedly. The Final /// parameter must be set to TRUE on the last call to CryptEncrypt, so that the encryption engine can properly finish /// the encryption process. The following extra actions are performed when Final is TRUE: /// /// /// /// /// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. If the data length equals /// the block size of the cipher, one additional block of padding is appended to the data. To find the block size of a cipher, use /// CryptGetKeyParam to get the KP_BLOCKLEN value of the key. /// /// /// /// /// If the cipher is operating in a chaining mode, the next CryptEncrypt operation resets the cipher's feedback register to /// the KP_IV value of the key. /// /// /// /// If the cipher is a stream cipher, the next CryptEncrypt resets the cipher to its initial state. /// /// /// /// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to /// TRUE. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of /// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and /// passing the duplicate key to the CryptEncrypt function. This causes the KP_IV of the original key to be placed in the /// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback /// register of the key will be changed. The following pseudocode shows how this can be done. /// /// /// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private /// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of plaintext data that can be /// encrypted with a call to CryptEncrypt with an RSA key is the length of the key modulus minus eleven bytes. The eleven /// bytes is the chosen minimum for PKCS #1 padding. The ciphertext is returned in little-endian format. /// /// Examples /// For examples that use this function, see Example C Program: Encrypting a File and Example C Program: Decrypting a File. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptencrypt BOOL CryptEncrypt( HCRYPTKEY hKey, // HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "697c4960-552b-4c3a-95cf-4632af56945b")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptEncryptFlags dwFlags, [In, Out] byte[] pbData, ref int pdwDataLen, int dwBufLen); /// /// The CryptEnumProviders function retrieves the first or next available cryptographic service providers (CSPs). Used in a loop, /// this function can retrieve in sequence all of the CSPs available on a computer. /// /// Possible CSPs include Microsoft Base Cryptographic Provider version 1.0 and Microsoft Enhanced Cryptographic Provider version 1.0. /// /// /// Index of the next provider to be enumerated. /// Reserved for future use and must be NULL. /// Reserved for future use and must be zero. /// Address of the DWORD value designating the type of the enumerated provider. /// /// /// A pointer to a buffer that receives the data from the enumerated provider. This is a string including the terminating null character. /// /// /// This parameter can be NULL to set the size of the name for memory allocation purposes. For more information, see /// Retrieving Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pszProvName parameter. When the /// function returns, the DWORD value contains the number of bytes stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually /// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to /// by this parameter is updated to reflect the actual size of the data copied to the buffer. /// /// /// /// If the function succeeds, the return value is nonzero ( TRUE). /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_MORE_DATA /// The pszProvName buffer was not large enough to hold the provider name. /// /// /// ERROR_NO_MORE_ITEMS /// There are no more items to enumerate. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// The operating system ran out of memory. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter has an unrecognized value. /// /// /// NTE_FAIL /// Something was wrong with the type registration. /// /// /// /// /// This function enumerates the providers available on a computer. The provider types can be enumerated by using CryptEnumProviderTypes. /// Examples /// /// The following example shows a loop listing all available cryptographic service providers. For another example that uses the /// CryptEnumProviders function, see Example C Program: Enumerating CSP Providers and Provider Types. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptenumprovidersa BOOL CryptEnumProvidersA( DWORD // dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPSTR szProvName, DWORD *pcbProvName ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "2d93ef0f-b48f-481b-ba62-c535476fde08")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptEnumProviders(uint dwIndex, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out uint pdwProvType, [Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szProvName, ref uint pcbProvName); /// /// The CryptEnumProviders function retrieves the first or next available cryptographic service providers (CSPs). Used in a loop, /// this function can retrieve in sequence all of the CSPs available on a computer. /// /// Possible CSPs include Microsoft Base Cryptographic Provider version 1.0 and Microsoft Enhanced Cryptographic Provider version 1.0. /// /// /// A sequence of provider names and types. [PInvokeData("wincrypt.h", MSDNShortId = "2d93ef0f-b48f-481b-ba62-c535476fde08")] public static IEnumerable<(uint provType, string provName)> CryptEnumProviders() { var idx = 0U; uint type; var sb = new StringBuilder(1024); var sz = 0U; while (CryptEnumProviders(idx, default, 0, out type, null, ref sz)) { sb.EnsureCapacity((int)sz); if (CryptEnumProviders(idx, default, 0, out type, sb, ref sz)) { yield return (type, sb.ToString()); ++idx; } else Win32Error.ThrowLastError(); } } /// /// The CryptEnumProviderTypes function retrieves the first or next types of cryptographic service provider (CSP) supported on the /// computer. Used in a loop, this function retrieves in sequence all of the CSP types available on a computer. /// Provider types include PROV_RSA_FULL, PROV_RSA_SCHANNEL, and PROV_DSS. /// /// Index of the next provider type to be enumerated. /// Reserved for future use and must be NULL. /// Reserved for future use and must be zero. /// Address of the DWORD value designating the enumerated provider type. /// /// /// A pointer to a buffer that receives the data from the enumerated provider type. This is a string including the terminating /// NULL character. Some provider types do not have display names, and in this case no name is returned and the returned /// value pointed to by pcbTypeName is zero. /// /// /// This parameter can be NULL to get the size of the name for memory allocation purposes. For more information, see /// Retrieving Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pszTypeName parameter. When the /// function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer. Some provider types /// do not have display names, and in this case no name is returned and the returned value pointed to by pcbTypeName is zero. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually /// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to /// by this parameter is updated to reflect the actual size of the data copied to the buffer. /// /// /// /// If the function succeeds, the return value is nonzero ( TRUE). /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_NO_MORE_ITEMS /// There are no more items to enumerate. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// The operating system ran out of memory. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter has an unrecognized value. /// /// /// NTE_FAIL /// Something was wrong with the type registration. /// /// /// /// /// /// This function enumerates the provider types available on a computer. Providers for any specific provider type can be enumerated /// using CryptEnumProviders. /// /// Examples /// The following example shows a loop listing all available cryptographic service provider types. /// /// For another example that uses the CryptEnumProviderTypes function, see Example C Program: Enumerating CSP Providers and /// Provider Types. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptenumprovidertypesa BOOL CryptEnumProviderTypesA( // DWORD dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPSTR szTypeName, DWORD *pcbTypeName ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "7568c963-4d06-4af0-bd15-240402425046")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptEnumProviderTypes(uint dwIndex, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out uint pdwProvType, [Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szTypeName, ref uint pcbTypeName); /// /// The CryptEnumProviderTypes function retrieves the first or next types of cryptographic service provider (CSP) supported on the /// computer. Used in a loop, this function retrieves in sequence all of the CSP types available on a computer. /// Provider types include PROV_RSA_FULL, PROV_RSA_SCHANNEL, and PROV_DSS. /// /// A sequence of provider type names and types. [PInvokeData("wincrypt.h", MSDNShortId = "7568c963-4d06-4af0-bd15-240402425046")] public static IEnumerable<(uint provType, string typeName)> CryptEnumProviderTypes() { var idx = 0U; var sb = new StringBuilder(1024); var sz = 0U; while (CryptEnumProviderTypes(idx, default, 0, out _, null, ref sz)) { sb.EnsureCapacity((int)sz); if (CryptEnumProviderTypes(idx, default, 0, out var type, sb, ref sz)) { yield return (type, sb.ToString()); ++idx; } else Win32Error.ThrowLastError(); } } /// /// A handle to the key to be exported is passed to the function, and the function returns a key BLOB. This key BLOB can be sent over /// a nonsecure transport or stored in a nonsecure storage location. This function can export an Schannel session key, regular /// session key, public key, or public/private key pair. The key BLOB to export is useless until the intended recipient uses the /// CryptImportKey function on it to import the key or key pair into a recipient's CSP. /// /// A handle to the key to be exported. /// /// /// A handle to a cryptographic key of the destination user. The key data within the exported key BLOB is encrypted using this key. /// This ensures that only the destination user is able to make use of the key BLOB. Both hExpKey and hKey must come /// from the same CSP. /// /// /// Most often, this is the key exchange public key of the destination user. However, certain protocols in some CSPs require that a /// session key belonging to the destination user be used for this purpose. /// /// /// If the key BLOB type specified by dwBlobType is PUBLICKEYBLOB, this parameter is unused and must be set to zero. /// /// /// If the key BLOB type specified by dwBlobType is PRIVATEKEYBLOB, this is typically a handle to a session key that is /// to be used to encrypt the key BLOB. Some CSPs allow this parameter to be zero, in which case the application must encrypt the /// private key BLOB manually so as to protect it. /// /// /// To determine how Microsoft cryptographic service providers respond to this parameter, see the private key BLOB sections of /// Microsoft Cryptographic Service Providers. /// /// /// Note Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for /// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished /// using the handle, release it by calling the CryptDestroyKey function. /// /// /// /// /// Specifies the type of key BLOB to be exported in pbData. This must be one of the following constants as discussed in /// Cryptographic Key Storage and Exchange. /// /// /// /// Value /// Meaning /// /// /// OPAQUEKEYBLOB /// /// Used to store session keys in an Schannel CSP or any other vendor-specific format. OPAQUEKEYBLOBs are nontransferable and must be /// used within the CSP that generated the BLOB. /// /// /// /// PRIVATEKEYBLOB /// Used to transport public/private key pairs. /// /// /// PUBLICKEYBLOB /// Used to transport public keys. /// /// /// SIMPLEBLOB /// Used to transport session keys. /// /// /// PLAINTEXTKEYBLOB /// A PLAINTEXTKEYBLOB used to export any key supported by the CSP in use. /// /// /// SYMMETRICWRAPKEYBLOB /// /// Used to export and import a symmetric key wrapped with another symmetric key. The actual wrapped key is in the format specified /// in the IETF RFC 3217 standard. /// /// /// /// /// /// /// Specifies additional options for the function. This parameter can be zero or a combination of one or more of the following values. /// /// /// /// Value /// Meaning /// /// /// CRYPT_BLOB_VER3 0x00000080 /// This flag causes this function to export version 3 of a BLOB type. /// /// /// CRYPT_DESTROYKEY 0x00000004 /// This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only. /// /// /// CRYPT_OAEP 0x00000040 /// This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs. /// /// /// CRYPT_SSL2_FALLBACK 0x00000002 /// /// The first eight bytes of the RSA encryption block padding must be set to 0x03 rather than to random data. This prevents version /// rollback attacks and is discussed in the SSL3 specification. This flag is available for Schannel CSPs only. /// /// /// /// CRYPT_Y_ONLY 0x00000001 /// This flag is not used. /// /// /// /// /// /// A pointer to a buffer that receives the key BLOB data. The format of this BLOB varies depending on the BLOB type requested in the /// dwBlobType parameter. For the format for PRIVATEKEYBLOBs, PUBLICKEYBLOBs, and SIMPLEBLOBs, see Base Provider Key BLOBs. /// /// /// If this parameter is NULL, the required buffer size is placed in the value pointed to by the pdwDataLen parameter. /// For more information, see Retrieving Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value that, on entry, contains the size, in bytes, of the buffer pointed to by the pbData /// parameter. When the function returns, this value contains the number of bytes stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are usually specified /// large enough to ensure that the largest possible output data fits in the buffer. On output, the variable pointed to by this /// parameter is updated to reflect the actual size of the data copied to the buffer. /// /// To retrieve the required size of the pbData buffer, pass NULL for pbData.The required buffer size will /// be placed in the value pointed to by this parameter. /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular CSP being used. The following table shows some of the possible /// error codes. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_MORE_DATA /// /// If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the /// ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen. /// /// /// /// NTE_BAD_DATA /// /// Either the algorithm that works with the public key to be exported is not supported by this CSP, or an attempt was made to export /// a session key that was encrypted with something other than one of your public keys. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_KEY /// One or both of the keys specified by hKey and hExpKey are not valid. /// /// /// NTE_BAD_KEY_STATE /// /// You do not have permission to export the key. That is, when the hKey key was created, the CRYPT_EXPORTABLE flag was not specified. /// /// /// /// NTE_BAD_PUBLIC_KEY /// The key BLOB type specified by dwBlobType is PUBLICKEYBLOB, but hExpKey does not contain a public key handle. /// /// /// NTE_BAD_TYPE /// The dwBlobType parameter specifies an unknown BLOB type. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hKey key was created cannot be found. /// /// /// NTE_NO_KEY /// A session key is being exported, and the hExpKey parameter does not specify a public key. /// /// /// /// /// /// For any of the DES key permutations that use a PLAINTEXTKEYBLOB, only the full key size, including parity bit, may be exported. /// The following key sizes are supported. /// /// /// /// Algorithm /// Supported key size /// /// /// CALG_DES /// 64 bits /// /// /// CALG_3DES_112 /// 128 bits /// /// /// CALG_3DES /// 192 bits /// /// /// Examples /// /// The following example shows how to export a cryptographic key or a key pair in a more secure manner. This example assumes that a /// cryptographic context has been acquired and that a public key is available for export. For an example that includes the complete /// context for using this function, see Example C Program: Signing a Hash and Verifying the Hash Signature. For another example that /// uses this function, see Example C Program: Exporting a Session Key. /// /// #include <windows.h> /// #include <stdio.h> /// #include <Wincrypt.h> /// /// BOOL GetExportedKey( HCRYPTKEY hKey, DWORD dwBlobType, LPBYTE *ppbKeyBlob, LPDWORD pdwBlobLen) { /// DWORD dwBlobLength; /// *ppbKeyBlob = NULL; /// *pdwBlobLen = 0; /// // Export the public key. Here the public key is exported to a /// // PUBLICKEYBLOB. This BLOB can be written to a file and /// // sent to another user. /// if(CryptExportKey( hKey, NULL, dwBlobType, 0, NULL, &dwBlobLength)) { /// printf("Size of the BLOB for the public key determined. \n"); /// } else { /// printf("Error computing BLOB length.\n"); /// return FALSE; /// } /// // Allocate memory for the pbKeyBlob. /// if(*ppbKeyBlob = (LPBYTE)malloc(dwBlobLength)) { /// printf("Memory has been allocated for the BLOB. \n"); } /// else { /// printf("Out of memory. \n"); /// return FALSE; /// } /// // Do the actual exporting into the key BLOB. /// if(CryptExportKey( hKey, NULL, dwBlobType, 0, *ppbKeyBlob, &dwBlobLength)) { /// printf("Contents have been written to the BLOB. \n"); /// *pdwBlobLen = dwBlobLength; } /// else { /// printf("Error exporting key.\n"); /// free(*ppbKeyBlob); /// *ppbKeyBlob = NULL; /// return FALSE; /// } /// return TRUE; /// } /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptexportkey // BOOL CryptExportKey( [in] HCRYPTKEY hKey, [in] HCRYPTKEY hExpKey, [in] DWORD dwBlobType, [in] DWORD dwFlags, [out] BYTE *pbData, [in, out] DWORD *pdwDataLen ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "NF:wincrypt.CryptExportKey")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, BlobType dwBlobType, CryptExportKeyFlags dwFlags, [Out, Optional] IntPtr pbData, ref uint pdwDataLen); /// /// A handle to the key to be exported is passed to the function, and the function returns a key BLOB. This key BLOB can be sent over /// a nonsecure transport or stored in a nonsecure storage location. This function can export an Schannel session key, regular /// session key, public key, or public/private key pair. The key BLOB to export is useless until the intended recipient uses the /// CryptImportKey function on it to import the key or key pair into a recipient's CSP. /// /// A handle to the key to be exported. /// /// /// A handle to a cryptographic key of the destination user. The key data within the exported key BLOB is encrypted using this key. /// This ensures that only the destination user is able to make use of the key BLOB. Both hExpKey and hKey must come /// from the same CSP. /// /// /// Most often, this is the key exchange public key of the destination user. However, certain protocols in some CSPs require that a /// session key belonging to the destination user be used for this purpose. /// /// /// If the key BLOB type specified by dwBlobType is PUBLICKEYBLOB, this parameter is unused and must be set to zero. /// /// /// If the key BLOB type specified by dwBlobType is PRIVATEKEYBLOB, this is typically a handle to a session key that is /// to be used to encrypt the key BLOB. Some CSPs allow this parameter to be zero, in which case the application must encrypt the /// private key BLOB manually so as to protect it. /// /// /// To determine how Microsoft cryptographic service providers respond to this parameter, see the private key BLOB sections of /// Microsoft Cryptographic Service Providers. /// /// /// Note Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for /// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished /// using the handle, release it by calling the CryptDestroyKey function. /// /// /// /// /// Specifies the type of key BLOB to be exported in pbData. This must be one of the following constants as discussed in /// Cryptographic Key Storage and Exchange. /// /// /// /// Value /// Meaning /// /// /// OPAQUEKEYBLOB /// /// Used to store session keys in an Schannel CSP or any other vendor-specific format. OPAQUEKEYBLOBs are nontransferable and must be /// used within the CSP that generated the BLOB. /// /// /// /// PRIVATEKEYBLOB /// Used to transport public/private key pairs. /// /// /// PUBLICKEYBLOB /// Used to transport public keys. /// /// /// SIMPLEBLOB /// Used to transport session keys. /// /// /// PLAINTEXTKEYBLOB /// A PLAINTEXTKEYBLOB used to export any key supported by the CSP in use. /// /// /// SYMMETRICWRAPKEYBLOB /// /// Used to export and import a symmetric key wrapped with another symmetric key. The actual wrapped key is in the format specified /// in the IETF RFC 3217 standard. /// /// /// /// /// /// /// Specifies additional options for the function. This parameter can be zero or a combination of one or more of the following values. /// /// /// /// Value /// Meaning /// /// /// CRYPT_BLOB_VER3 0x00000080 /// This flag causes this function to export version 3 of a BLOB type. /// /// /// CRYPT_DESTROYKEY 0x00000004 /// This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only. /// /// /// CRYPT_OAEP 0x00000040 /// This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs. /// /// /// CRYPT_SSL2_FALLBACK 0x00000002 /// /// The first eight bytes of the RSA encryption block padding must be set to 0x03 rather than to random data. This prevents version /// rollback attacks and is discussed in the SSL3 specification. This flag is available for Schannel CSPs only. /// /// /// /// CRYPT_Y_ONLY 0x00000001 /// This flag is not used. /// /// /// /// /// /// A pointer to a buffer that receives the key BLOB data. The format of this BLOB varies depending on the BLOB type requested in the /// dwBlobType parameter. For the format for PRIVATEKEYBLOBs, PUBLICKEYBLOBs, and SIMPLEBLOBs, see Base Provider Key BLOBs. /// /// /// If this parameter is NULL, the required buffer size is placed in the value pointed to by the pdwDataLen parameter. /// For more information, see Retrieving Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value that, on entry, contains the size, in bytes, of the buffer pointed to by the pbData /// parameter. When the function returns, this value contains the number of bytes stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are usually specified /// large enough to ensure that the largest possible output data fits in the buffer. On output, the variable pointed to by this /// parameter is updated to reflect the actual size of the data copied to the buffer. /// /// To retrieve the required size of the pbData buffer, pass NULL for pbData.The required buffer size will /// be placed in the value pointed to by this parameter. /// /// /// If the function succeeds, the function returns nonzero ( TRUE). /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular CSP being used. The following table shows some of the possible /// error codes. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_MORE_DATA /// /// If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the /// ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen. /// /// /// /// NTE_BAD_DATA /// /// Either the algorithm that works with the public key to be exported is not supported by this CSP, or an attempt was made to export /// a session key that was encrypted with something other than one of your public keys. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_KEY /// One or both of the keys specified by hKey and hExpKey are not valid. /// /// /// NTE_BAD_KEY_STATE /// /// You do not have permission to export the key. That is, when the hKey key was created, the CRYPT_EXPORTABLE flag was not specified. /// /// /// /// NTE_BAD_PUBLIC_KEY /// The key BLOB type specified by dwBlobType is PUBLICKEYBLOB, but hExpKey does not contain a public key handle. /// /// /// NTE_BAD_TYPE /// The dwBlobType parameter specifies an unknown BLOB type. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hKey key was created cannot be found. /// /// /// NTE_NO_KEY /// A session key is being exported, and the hExpKey parameter does not specify a public key. /// /// /// /// /// /// For any of the DES key permutations that use a PLAINTEXTKEYBLOB, only the full key size, including parity bit, may be exported. /// The following key sizes are supported. /// /// /// /// Algorithm /// Supported key size /// /// /// CALG_DES /// 64 bits /// /// /// CALG_3DES_112 /// 128 bits /// /// /// CALG_3DES /// 192 bits /// /// /// Examples /// /// The following example shows how to export a cryptographic key or a key pair in a more secure manner. This example assumes that a /// cryptographic context has been acquired and that a public key is available for export. For an example that includes the complete /// context for using this function, see Example C Program: Signing a Hash and Verifying the Hash Signature. For another example that /// uses this function, see Example C Program: Exporting a Session Key. /// /// #include <windows.h> /// #include <stdio.h> /// #include <Wincrypt.h> /// /// BOOL GetExportedKey( HCRYPTKEY hKey, DWORD dwBlobType, LPBYTE *ppbKeyBlob, LPDWORD pdwBlobLen) { /// DWORD dwBlobLength; /// *ppbKeyBlob = NULL; /// *pdwBlobLen = 0; /// // Export the public key. Here the public key is exported to a /// // PUBLICKEYBLOB. This BLOB can be written to a file and /// // sent to another user. /// if(CryptExportKey( hKey, NULL, dwBlobType, 0, NULL, &dwBlobLength)) { /// printf("Size of the BLOB for the public key determined. \n"); /// } else { /// printf("Error computing BLOB length.\n"); /// return FALSE; /// } /// // Allocate memory for the pbKeyBlob. /// if(*ppbKeyBlob = (LPBYTE)malloc(dwBlobLength)) { /// printf("Memory has been allocated for the BLOB. \n"); } /// else { /// printf("Out of memory. \n"); /// return FALSE; /// } /// // Do the actual exporting into the key BLOB. /// if(CryptExportKey( hKey, NULL, dwBlobType, 0, *ppbKeyBlob, &dwBlobLength)) { /// printf("Contents have been written to the BLOB. \n"); /// *pdwBlobLen = dwBlobLength; } /// else { /// printf("Error exporting key.\n"); /// free(*ppbKeyBlob); /// *ppbKeyBlob = NULL; /// return FALSE; /// } /// return TRUE; /// } /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptexportkey // BOOL CryptExportKey( [in] HCRYPTKEY hKey, [in] HCRYPTKEY hExpKey, [in] DWORD dwBlobType, [in] DWORD dwFlags, [out] BYTE *pbData, [in, out] DWORD *pdwDataLen ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "NF:wincrypt.CryptExportKey")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, BlobType dwBlobType, CryptExportKeyFlags dwFlags, [Out, Optional] byte[] pbData, ref uint pdwDataLen); /// /// /// The CryptGenKey function generates a random cryptographic session key or a public/private key pair. A handle to the key or key /// pair is returned in phKey. This handle can then be used as needed with any CryptoAPI function that requires a key handle. /// /// /// The calling application must specify the algorithm when calling this function. Because this algorithm type is kept bundled with /// the key, the application does not need to specify the algorithm later when the actual cryptographic operations are performed. /// /// /// A handle to a cryptographic service provider (CSP) created by a call to CryptAcquireContext. /// /// /// An ALG_ID value that identifies the algorithm for which the key is to be generated. Values for this parameter vary depending on /// the CSP used. /// /// For ALG_ID values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms. /// /// For ALG_ID values to use with the Microsoft Strong Cryptographic Provider or the Microsoft Enhanced Cryptographic /// Provider, see Enhanced Provider Algorithms. /// /// For a Diffie-Hellman CSP, use one of the following values. /// /// /// Value /// Meaning /// /// /// CALG_DH_EPHEM /// Specifies an "Ephemeral" Diffie-Hellman key. /// /// /// CALG_DH_SF /// Specifies a "Store and Forward" Diffie-Hellman key. /// /// /// /// In addition to generating session keys for symmetric algorithms, this function can also generate public/private key pairs. Each /// CryptoAPI client generally possesses two public/private key pairs. To generate one of these key pairs, set the Algid parameter /// to one of the following values. /// /// /// /// Value /// Meaning /// /// /// AT_KEYEXCHANGE /// Key exchange /// /// /// AT_SIGNATURE /// Digital signature /// /// /// /// Note When key specifications AT_KEYEXCHANGE and AT_SIGNATURE are specified, the algorithm identifiers that are used to /// generate the key depend on the provider used. As a result, for these key specifications, the values returned from /// CryptGetKeyParam (when the KP_ALGID parameter is specified) depend on the provider used. To determine which algorithm identifier /// is used by the different providers for the key specs AT_KEYEXCHANGE and AT_SIGNATURE, see ALG_ID. /// /// /// /// /// Specifies the type of key generated. The sizes of a session key, RSA signature key, and RSA key exchange keys can be set when /// the key is generated. The key size, representing the length of the key modulus in bits, is set with the upper 16 bits of this /// parameter. Thus, if a 2,048-bit RSA signature key is to be generated, the value 0x08000000 is combined with any other dwFlags /// predefined value with a bitwise- OR operation. The upper 16 bits of 0x08000000 is 0x0800, or decimal 2,048. The /// RSA1024BIT_KEY value can be used to specify a 1024-bit RSA key. /// /// /// Due to changing export control restrictions, the default CSP and default key length may change between operating system /// versions. It is important that both the encryption and decryption use the same CSP and that the key length be explicitly set /// using the dwFlags parameter to ensure interoperability on different operating system platforms. /// /// /// In particular, the default RSA Full Cryptographic Service Provider is the Microsoft RSA Strong Cryptographic Provider. The /// default DSS Signature Diffie-Hellman Cryptographic Service Provider is the Microsoft Enhanced DSS Diffie-Hellman Cryptographic /// Provider. Each of these CSPs has a default 128-bit symmetric key length for RC2 and RC4 and a 1,024-bit default key length for /// public key algorithms. /// /// /// If the upper 16 bits is zero, the default key size is generated. If a key larger than the maximum or smaller than the minimum is /// specified, the call fails with the ERROR_INVALID_PARAMETER code. /// /// The following table lists minimum, default, and maximum signature and exchange key lengths beginning with Windows XP. /// /// /// Key type and provider /// Minimum length /// Default length /// Maximum length /// /// /// RSA Base Provider Signature and ExchangeKeys /// 384 /// 512 /// 16,384 /// /// /// RSA Strong and Enhanced Providers Signature and Exchange Keys /// 384 /// 1,024 /// 16,384 /// /// /// DSS Base Providers Signature Keys /// 512 /// 1,024 /// 1,024 /// /// /// DSS Base Providers Exchange Keys /// Not applicable /// Not applicable /// Not applicable /// /// /// DSS/DH Base Providers Signature Keys /// 512 /// 1,024 /// 1,024 /// /// /// DSS/DH Base Providers Exchange Keys /// 512 /// 512 /// 1,024 /// /// /// DSS/DH Enhanced Providers Signature Keys /// 512 /// 1,024 /// 1,024 /// /// /// DSS/DH Enhanced Providers Exchange Keys /// 512 /// 1,024 /// 4,096 /// /// /// For session key lengths, see CryptDeriveKey. /// For more information about keys generated using Microsoft providers, see Microsoft Cryptographic Service Providers. /// The lower 16-bits of this parameter can be zero or a combination of one or more of the following values. /// /// /// Value /// Meaning /// /// /// CRYPT_ARCHIVABLE /// /// If this flag is set, the key can be exported until its handle is closed by a call to CryptDestroyKey. This allows newly /// generated keys to be exported upon creation for archiving or key recovery. After the handle is closed, the key is no longer exportable. /// /// /// /// CRYPT_CREATE_IV /// This flag is not used. /// /// /// CRYPT_CREATE_SALT /// /// If this flag is set, then the key is assigned a random salt value automatically. You can retrieve this salt value by using the /// CryptGetKeyParam function with the dwParam parameter set to KP_SALT. If this flag is not set, then the key is given a salt value /// of zero. When keys with nonzero salt values are exported (through CryptExportKey), then the salt value must also be obtained and /// kept with the key BLOB. /// /// /// /// CRYPT_DATA_KEY /// This flag is not used. /// /// /// CRYPT_EXPORTABLE /// /// If this flag is set, then the key can be transferred out of the CSP into a key BLOB by using the CryptExportKey function. /// Because session keys generally must be exportable, this flag should usually be set when they are created. If this flag is not /// set, then the key is not exportable. For a session key, this means that the key is available only within the current session and /// only the application that created it will be able to use it. For a public/private key pair, this means that the private key /// cannot be transported or backed up. This flag applies only to session key and private key BLOBs. It does not apply to public /// keys, which are always exportable. /// /// /// /// CRYPT_FORCE_KEY_PROTECTION_HIGH /// /// This flag specifies strong key protection. When this flag is set, the user is prompted to enter a password for the key when the /// key is created. The user will be prompted to enter the password whenever this key is used. This flag is only used by the CSPs /// that are provided by Microsoft. Third party CSPs will define their own behavior for strong key protection. Specifying this flag /// causes the same result as calling this function with the CRYPT_USER_PROTECTED flag when strong key protection is specified in /// the system registry. If this flag is specified and the provider handle in the hProv parameter was created by using the /// CRYPT_VERIFYCONTEXT or CRYPT_SILENT flag, this function will set the last error to NTE_SILENT_CONTEXT and return zero. Windows /// Server 2003 and Windows XP: This flag is not supported. /// /// /// /// CRYPT_KEK /// This flag is not used. /// /// /// CRYPT_INITIATOR /// This flag is not used. /// /// /// CRYPT_NO_SALT /// /// This flag specifies that a no salt value gets allocated for a forty-bit symmetric key. For more information, see Salt Value Functionality. /// /// /// /// CRYPT_ONLINE /// This flag is not used. /// /// /// CRYPT_PREGEN /// /// This flag specifies an initial Diffie-Hellman or DSS key generation. This flag is useful only with Diffie-Hellman and DSS CSPs. /// When used, a default key length will be used unless a key length is specified in the upper 16 bits of the dwFlags parameter. If /// parameters that involve key lengths are set on a PREGEN Diffie-Hellman or DSS key using CryptSetKeyParam, the key lengths must /// be compatible with the key length set here. /// /// /// /// CRYPT_RECIPIENT /// This flag is not used. /// /// /// CRYPT_SF /// This flag is not used. /// /// /// CRYPT_SGCKEY /// This flag is not used. /// /// /// CRYPT_USER_PROTECTED /// /// If this flag is set, the user is notified through a dialog box or another method when certain actions are attempting to use this /// key. The precise behavior is specified by the CSP being used. If the provider context was opened with the CRYPT_SILENT flag set, /// using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT. /// /// /// /// CRYPT_VOLATILE /// This flag is not used. /// /// /// /// /// Address to which the function copies the handle of the newly generated key. When you have finished using the key, delete the /// handle to the key by calling the CryptDestroyKey function. /// /// /// Returns nonzero if successful or zero otherwise. /// For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the /// following table. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The Algid parameter specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter contains a value that is not valid. /// /// /// NTE_BAD_UID /// The hProv parameter does not contain a valid context handle. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// NTE_SILENT_CONTEXT /// The provider could not perform the action because the context was acquired as silent. /// /// /// /// /// /// If keys are generated for symmetric block ciphers, the key, by default, is set up in cipher block chaining (CBC) mode with an /// initialization vector of zero. This cipher mode provides a good default method for bulk encrypting data. To change these /// parameters, use the CryptSetKeyParam function. /// /// To choose an appropriate key length, the following methods are recommended: /// /// /// /// Enumerate the algorithms that the CSP supports and get maximum and minimum key lengths for each algorithm. To do this, call /// CryptGetProvParam with PP_ENUMALGS_EX. /// /// /// /// /// Use the minimum and maximum lengths to choose an appropriate key length. It is not always advisable to choose the maximum length /// because this can lead to performance issues. /// /// /// /// After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length. /// /// /// Examples /// /// The following example shows the creation of a random session key. For an example that includes the complete context for this /// example, see Example C Program: Encrypting a File. For another example that uses this function, see Example C Program: /// Decrypting a File. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenkey BOOL CryptGenKey( HCRYPTPROV hProv, ALG_ID // Algid, DWORD dwFlags, HCRYPTKEY *phKey ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "b65dd856-2dfa-4cda-9b2f-b32f3c291470")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptGenKey(HCRYPTPROV hProv, ALG_ID Algid, CryptGenKeyFlags dwFlags, out SafeHCRYPTKEY phKey); /// The CryptGenRandom function fills a buffer with cryptographically random bytes. /// Handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext. /// Number of bytes of random data to be generated. /// /// Buffer to receive the returned data. This buffer must be at least dwLen bytes in length. /// Optionally, the application can fill this buffer with data to use as an auxiliary random seed. /// /// /// If the function succeeds, the return value is nonzero (TRUE). /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the /// following table. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_UID /// The hProv parameter does not contain a valid context handle. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// /// /// /// The data produced by this function is cryptographically random. It is far more random than the data generated by the typical /// random number generator such as the one shipped with your C compiler. /// /// This function is often used to generate random initialization vectors and salt values. /// /// Software random number generators work in fundamentally the same way. They start with a random number, known as the seed, and /// then use an algorithm to generate a pseudo-random sequence of bits based on it. The most difficult part of this process is to /// get a seed that is truly random. This is usually based on user input latency, or the jitter from one or more hardware components. /// /// /// With Microsoft CSPs, CryptGenRandom uses the same random number generator used by other security components. This allows /// numerous processes to contribute to a system-wide seed. CryptoAPI stores an intermediate random seed with every user. To form /// the seed for the random number generator, a calling application supplies bits it might have—for instance, mouse or keyboard /// timing input—that are then combined with both the stored seed and various system data and user data such as the process ID and /// thread ID, the system clock, the system time, the system counter, memory status, free disk clusters, the hashed user environment /// block. This result is used to seed the pseudorandom number generator (PRNG). In Windows Vista with Service Pack 1 (SP1) and /// later, an implementation of the AES counter-mode based PRNG specified in NIST Special Publication 800-90 is used. In Windows /// Vista, Windows Storage Server 2003, and Windows XP, the PRNG specified in Federal Information Processing Standard (FIPS) 186-2 /// is used. If an application has access to a good random source, it can fill the pbBuffer buffer with some random data before /// calling CryptGenRandom. The CSP then uses this data to further randomize its internal seed. It is acceptable to omit the /// step of initializing the pbBuffer buffer before calling CryptGenRandom. /// /// Examples /// /// The following example shows the generation of 8 random bytes. These can be used to create cryptographic keys or for any /// application that uses random numbers. For an example that includes the complete context for this example, see Example C Program: /// Duplicating a Session Key. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom BOOL CryptGenRandom( HCRYPTPROV hProv, // DWORD dwLen, BYTE *pbBuffer ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "3e5a437f-7439-43c9-a191-2908d2df0eb6")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptGenRandom(HCRYPTPROV hProv, uint dwLen, [In, Out] IntPtr pbBuffer); /// /// The CryptGetDefaultProvider function finds the default cryptographic service provider (CSP) of a specified provider type for the /// local computer or current user. The name of the default CSP for the provider type specified in the dwProvType parameter is /// returned in the pszProvName buffer. /// /// /// The provider type for which the default CSP name is to be found. /// Defined provider types are as follows: /// /// /// PROV_RSA_FULL /// /// /// PROV_RSA_SIG /// /// /// PROV_DSS /// /// /// PROV_DSS_DH /// /// /// PROV_DH_SCHANNEL /// /// /// PROV_FORTEZZA /// /// /// PROV_MS_EXCHANGE /// /// /// PROV_RSA_SCHANNEL /// /// /// PROV_SSL /// /// /// /// This parameter is reserved for future use and must be NULL. /// /// The following flag values are defined. /// /// /// Value /// Meaning /// /// /// CRYPT_USER_DEFAULT 0x00000002 /// Returns the user-context default CSP of the specified type. /// /// /// CRYPT_MACHINE_DEFAULT 0x00000001 /// Returns the computer default CSP of the specified type. /// /// /// /// /// A pointer to a null-terminated character string buffer to receive the name of the default CSP. /// /// To find the size of the buffer for memory allocation purposes, this parameter can be NULL. For more information, see /// Retrieving Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value that specifies the size, in bytes, of the buffer pointed to by the pszProvName parameter. When /// the function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually /// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to /// by this parameter is updated to reflect the actual size of the data copied to the buffer. /// /// /// /// If the function succeeds, the return value is nonzero ( TRUE). /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. /// The error code prefaced by NTE is generated by the particular CSP being used. Possible error codes include the following. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_MORE_DATA /// The buffer for the name is not large enough. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// The operating system ran out of memory. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter has an unrecognized value. /// /// /// /// /// /// This function determines which installed CSP is currently set as the default for the local computer or current user. This /// information is often displayed to the user. /// /// Examples /// /// The following example retrieves the name of the default CSP for the PROV_RSA_FULL provider type. For another example that uses /// this function, see Example C Program: Enumerating CSP Providers and Provider Types. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetdefaultprovidera BOOL CryptGetDefaultProviderA( // DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "5d15641e-1ad7-441d-9423-65fd51de9812")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptGetDefaultProvider(uint dwProvType, [Optional] IntPtr pdwReserved, CryptProviderFlags dwFlags, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszProvName, ref uint pcbProvName); /// /// The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be /// retrieved by using this function. /// /// Handle of the hash object to be queried. /// /// Query type. This parameter can be set to one of the following queries. /// /// /// Value /// Meaning /// /// /// HP_ALGID Hash algorithm /// /// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash. /// /// /// /// HP_HASHSIZE Hash value size /// /// DWORD value indicating the number of bytes in the hash value. This value will vary depending on the hash algorithm. Applications /// must retrieve this value just before the HP_HASHVAL value so the correct amount of memory can be allocated. /// /// /// /// HP_HASHVAL Hash value /// /// The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to the /// hash object earlier through the CryptHashData and CryptHashSessionKey functions. The CryptGetHashParam function completes the /// hash. After CryptGetHashParam has been called, no more data can be added to the hash. Additional calls to CryptHashData or /// CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be called to destroy the hash object. /// /// /// /// Note CSPs can add more values that this function can query. /// /// /// A pointer to a buffer that receives the specified value data. The form of this data varies, depending on the value number. /// This parameter can be NULL to determine the memory size required. /// /// /// /// A pointer to a DWORD value specifying the size, in bytes, of the pbData buffer. When the function returns, the /// DWORD value contains the number of bytes stored in the buffer. /// /// If pbData is NULL, set the value of pdwDataLen to zero. /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually /// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to /// by this parameter is updated to reflect the actual size of the data copied to the buffer. /// /// /// Reserved for future use and must be zero. /// /// If the function succeeds, the return value is TRUE. /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_MORE_DATA /// /// If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the /// ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hash object specified by the hHash parameter is not valid. /// /// /// NTE_BAD_TYPE /// The dwParam parameter specifies an unknown value number. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hash was created cannot be found. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgethashparam BOOL CryptGetHashParam( HCRYPTHASH // hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "ed008c07-1a40-4075-bdaa-eb7f7e12d9c3")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptGetHashParam(HCRYPTHASH hHash, HashParam dwParam, [Out, Optional] IntPtr pbData, ref uint pdwDataLen, uint dwFlags = 0); /// /// The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be /// retrieved by using this function. /// /// The expected return type. /// Handle of the hash object to be queried. /// /// Query type. This parameter can be set to one of the following queries. /// /// /// Value /// Meaning /// /// /// HP_ALGID Hash algorithm /// /// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash. /// /// /// /// HP_HASHSIZE Hash value size /// /// DWORD value indicating the number of bytes in the hash value. This value will vary depending on the hash algorithm. Applications /// must retrieve this value just before the HP_HASHVAL value so the correct amount of memory can be allocated. /// /// /// /// HP_HASHVAL Hash value /// /// The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to the /// hash object earlier through the CryptHashData and CryptHashSessionKey functions. The CryptGetHashParam function completes the /// hash. After CryptGetHashParam has been called, no more data can be added to the hash. Additional calls to CryptHashData or /// CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be called to destroy the hash object. /// /// /// /// Note CSPs can add more values that this function can query. /// /// The specified value data. The form of this data varies, depending on the value number. public static T CryptGetHashParam(HCRYPTHASH hHash, HashParam dwParam) => CryptGetValue(CryptGetHashParam, hHash, dwParam); /// /// The CryptGetKeyParam function retrieves data that governs the operations of a key. If the Microsoft Cryptographic Service /// Provider is used, the base symmetric keying material is not obtainable by this or any other function. /// /// The handle of the key being queried. /// /// Specifies the type of query being made. /// For all key types, this parameter can contain one of the following values. /// /// /// Value /// Meaning /// /// /// KP_ALGID /// /// Retrieve the key algorithm. The pbData parameter is a pointer to an ALG_ID value that receives the identifier of the algorithm /// that was specified when the key was created. When AT_KEYEXCHANGE or AT_SIGNATURE is specified for the Algid parameter of the /// CryptGenKey function, the algorithm identifiers that are used to generate the key depend on the provider used. For more /// information, see ALG_ID. /// /// /// /// KP_BLOCKLEN /// /// If a session key is specified by the hKey parameter, retrieve the block length of the key cipher. The pbData parameter is a /// pointer to a DWORD value that receives the block length, in bits. For stream ciphers, this value is always zero. If a /// public/private key pair is specified by hKey, retrieve the encryption granularity of the key pair. The pbData parameter is a /// pointer to a DWORD value that receives the encryption granularity, in bits. For example, the Microsoft Base Cryptographic /// Provider generates 512-bit RSA key pairs, so a value of 512 is returned for these keys. If the public key algorithm does not /// support encryption, the value retrieved is undefined. /// /// /// /// KP_CERTIFICATE /// /// pbData is the address of a buffer that receives the X.509 certificate that has been encoded by using Distinguished Encoding /// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key. /// /// /// /// KP_GET_USE_COUNT /// This value is not used. /// /// /// KP_KEYLEN /// /// Retrieve the actual length of the key. The pbData parameter is a pointer to a DWORD value that receives the key length, in bits. /// KP_KEYLEN can be used to get the length of any key type. Microsoft cryptographic service providers (CSPs) return a key length of /// 64 bits for CALG_DES, 128 bits for CALG_3DES_112, and 192 bits for CALG_3DES. These lengths are different from the lengths /// returned when you are enumerating algorithms with the dwParam value of the CryptGetProvParam function set to PP_ENUMALGS. The /// length returned by this call is the actual size of the key, including the parity bits included in the key. Microsoft CSPs that /// support the CALG_CYLINK_MEK ALG_ID return 64 bits for that algorithm. CALG_CYLINK_MEK is a 40-bit key but has parity and zeroed /// key bits to make the key length 64 bits. /// /// /// /// KP_SALT /// /// Retrieve the salt value of the key. The pbData parameter is a pointer to a BYTE array that receives the salt value in /// little-endian form. The size of the salt value varies depending on the CSP and algorithm being used. Salt values do not apply to /// public/private key pairs. /// /// /// /// KP_PERMISSIONS /// /// Retrieve the key permissions. The pbData parameter is a pointer to a DWORD value that receives the permission flags for the key. /// The following permission identifiers are currently defined. The key permissions can be zero or a combination of one or more of /// the following values. CRYPT_ARCHIVE Allow export during the lifetime of the handle of the key. This permission can be set only /// if it is already set in the internal permissions field of the key. Attempts to clear this permission are ignored. CRYPT_DECRYPT /// Allow decryption. CRYPT_ENCRYPT Allow encryption. CRYPT_EXPORT Allow the key to be exported. CRYPT_EXPORT_KEY Allow the key to /// be used for exporting keys. CRYPT_IMPORT_KEY Allow the key to be used for importing keys. CRYPT_MAC Allow Message Authentication /// Codes (MACs) to be used with key. CRYPT_READ Allow values to be read. CRYPT_WRITE Allow values to be set. /// /// /// /// /// If a Digital Signature Standard (DSS) key is specified by the hKey parameter, the dwParam value can also be set to one of the /// following values. /// /// /// /// Value /// Meaning /// /// /// KP_P /// /// Retrieve the modulus prime number P of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in /// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// /// /// /// KP_Q /// /// Retrieve the modulus prime number Q of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in /// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// /// /// /// KP_G /// /// Retrieve the generator G of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in little-endian /// form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// /// /// /// /// If a block cipher session key is specified by the hKey parameter, the dwParam value can also be set to one of the following values. /// /// /// /// Value /// Meaning /// /// /// KP_EFFECTIVE_KEYLEN /// /// Retrieve the effective key length of an RC2 key. The pbData parameter is a pointer to a DWORD value that receives the effective /// key length. /// /// /// /// KP_IV /// /// Retrieve the initialization vector of the key. The pbData parameter is a pointer to a BYTE array that receives the /// initialization vector. The size of this array is the block size, in bytes. For example, if the block length is 64 bits, the /// initialization vector consists of 8 bytes. /// /// /// /// KP_PADDING /// /// Retrieve the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that identifies /// the padding method used by the cipher. This can be one of the following values. PKCS5_PADDING Specifies the PKCS 5 (sec 6.2) /// padding method. RANDOM_PADDING The padding uses random numbers. This padding method is not supported by the Microsoft supplied /// CSPs. ZERO_PADDING The padding uses zeros. This padding method is not supported by the Microsoft supplied CSPs. /// /// /// /// KP_MODE /// /// Retrieve the cipher mode. The pbData parameter is a pointer to a DWORD value that receives a cipher mode identifier. For more /// information about cipher modes, see Data Encryption and Decryption. The following cipher mode identifiers are currently defined. /// CRYPT_MODE_CBC The cipher mode is cipher block chaining. CRYPT_MODE_CFB The cipher mode is cipher feedback (CFB). Microsoft CSPs /// currently support only 8-bit feedback in cipher feedback mode. CRYPT_MODE_ECB The cipher mode is electronic codebook. /// CRYPT_MODE_OFB The cipher mode is Output Feedback (OFB). Microsoft CSPs currently do not support Output Feedback Mode. /// CRYPT_MODE_CTS The cipher mode is ciphertext stealing mode. /// /// /// /// KP_MODE_BITS /// /// Retrieve the number of bits to feed back. The pbData parameter is a pointer to a DWORD value that receives the number of bits /// that are processed per cycle when the OFB or CFB cipher modes are used. /// /// /// /// /// If a Diffie-Hellman algorithm or Digital Signature Algorithm (DSA) key is specified by hKey, the dwParam value can also be set /// to the following value. /// /// /// /// Value /// Meaning /// /// /// KP_VERIFY_PARAMS /// /// Verifies the parameters of a Diffie-Hellman algorithm or DSA key. The pbData parameter is not used, and the value pointed to by /// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise. /// /// /// /// KP_KEYVAL /// /// This value is not used. Windows Vista, Windows Server 2003 and Windows XP: Retrieve the secret agreement value from an imported /// Diffie-Hellman algorithm key of type CALG_AGREEDKEY_ANY. The pbData parameter is the address of a buffer that receives the /// secret agreement value, in little-endian format. This buffer must be the same length as the key. The dwFlags parameter must be /// set to 0xF42A19B6. This property can only be retrieved by a thread running under the local system account.This property is /// available for use in the operating systems listed above. It may be altered or unavailable in subsequent versions. /// /// /// /// If a certificate is specified by hKey, the dwParam value can also be set to the following value. /// /// /// Value /// Meaning /// /// /// KP_CERTIFICATE /// /// A buffer that contains the DER-encoded X.509 certificate. The pbData parameter is not used, and the value pointed to by /// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise. /// /// /// /// /// /// A pointer to a buffer that receives the data. The form of this data depends on the value of dwParam. /// /// If the size of this buffer is not known, the required size can be retrieved at run time by passing NULL for this /// parameter and setting the value pointed to by pdwDataLen to zero. This function will place the required size of the buffer, in /// bytes, in the value pointed to by pdwDataLen. For more information, see Retrieving Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value that, on entry, contains the size, in bytes, of the buffer pointed to by the pbData parameter. /// When the function returns, the DWORD value contains the number of bytes stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size may be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are sometimes /// specified large enough to ensure that the largest possible output data fits in the buffer. On output, the variable pointed to by /// this parameter is updated to reflect the actual size of the data copied to the buffer. /// /// /// This parameter is reserved for future use and must be set to zero. /// /// If the function succeeds, the function returns nonzero. /// If the function fails, it returns zero. For extended error information, call GetLastError. /// /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes include the following. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_MORE_DATA /// /// If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the /// ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_KEY or NTE_NO_KEY /// The key specified by the hKey parameter is not valid. /// /// /// NTE_BAD_TYPE /// The dwParam parameter specifies an unknown value number. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the key was created cannot be found. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetkeyparam BOOL CryptGetKeyParam( HCRYPTKEY hKey, // DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "07956d74-0e22-484b-9bf1-e0184a2ff32f")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptGetKeyParam(HCRYPTKEY hKey, KeyParam dwParam, [Out, Optional] IntPtr pbData, ref uint pdwDataLen, uint dwFlags = 0); /// /// The CryptGetKeyParam function retrieves data that governs the operations of a key. If the Microsoft Cryptographic Service /// Provider is used, the base symmetric keying material is not obtainable by this or any other function. /// /// The expected return type. /// The handle of the key being queried. /// /// Specifies the type of query being made. /// For all key types, this parameter can contain one of the following values. /// /// /// Value /// Meaning /// /// /// KP_ALGID /// /// Retrieve the key algorithm. The pbData parameter is a pointer to an ALG_ID value that receives the identifier of the algorithm /// that was specified when the key was created. When AT_KEYEXCHANGE or AT_SIGNATURE is specified for the Algid parameter of the /// CryptGenKey function, the algorithm identifiers that are used to generate the key depend on the provider used. For more /// information, see ALG_ID. /// /// /// /// KP_BLOCKLEN /// /// If a session key is specified by the hKey parameter, retrieve the block length of the key cipher. The pbData parameter is a /// pointer to a DWORD value that receives the block length, in bits. For stream ciphers, this value is always zero. If a /// public/private key pair is specified by hKey, retrieve the encryption granularity of the key pair. The pbData parameter is a /// pointer to a DWORD value that receives the encryption granularity, in bits. For example, the Microsoft Base Cryptographic /// Provider generates 512-bit RSA key pairs, so a value of 512 is returned for these keys. If the public key algorithm does not /// support encryption, the value retrieved is undefined. /// /// /// /// KP_CERTIFICATE /// /// pbData is the address of a buffer that receives the X.509 certificate that has been encoded by using Distinguished Encoding /// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key. /// /// /// /// KP_GET_USE_COUNT /// This value is not used. /// /// /// KP_KEYLEN /// /// Retrieve the actual length of the key. The pbData parameter is a pointer to a DWORD value that receives the key length, in bits. /// KP_KEYLEN can be used to get the length of any key type. Microsoft cryptographic service providers (CSPs) return a key length of /// 64 bits for CALG_DES, 128 bits for CALG_3DES_112, and 192 bits for CALG_3DES. These lengths are different from the lengths /// returned when you are enumerating algorithms with the dwParam value of the CryptGetProvParam function set to PP_ENUMALGS. The /// length returned by this call is the actual size of the key, including the parity bits included in the key. Microsoft CSPs that /// support the CALG_CYLINK_MEK ALG_ID return 64 bits for that algorithm. CALG_CYLINK_MEK is a 40-bit key but has parity and zeroed /// key bits to make the key length 64 bits. /// /// /// /// KP_SALT /// /// Retrieve the salt value of the key. The pbData parameter is a pointer to a BYTE array that receives the salt value in /// little-endian form. The size of the salt value varies depending on the CSP and algorithm being used. Salt values do not apply to /// public/private key pairs. /// /// /// /// KP_PERMISSIONS /// /// Retrieve the key permissions. The pbData parameter is a pointer to a DWORD value that receives the permission flags for the key. /// The following permission identifiers are currently defined. The key permissions can be zero or a combination of one or more of /// the following values. CRYPT_ARCHIVE Allow export during the lifetime of the handle of the key. This permission can be set only /// if it is already set in the internal permissions field of the key. Attempts to clear this permission are ignored. CRYPT_DECRYPT /// Allow decryption. CRYPT_ENCRYPT Allow encryption. CRYPT_EXPORT Allow the key to be exported. CRYPT_EXPORT_KEY Allow the key to /// be used for exporting keys. CRYPT_IMPORT_KEY Allow the key to be used for importing keys. CRYPT_MAC Allow Message Authentication /// Codes (MACs) to be used with key. CRYPT_READ Allow values to be read. CRYPT_WRITE Allow values to be set. /// /// /// /// /// If a Digital Signature Standard (DSS) key is specified by the hKey parameter, the dwParam value can also be set to one of the /// following values. /// /// /// /// Value /// Meaning /// /// /// KP_P /// /// Retrieve the modulus prime number P of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in /// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// /// /// /// KP_Q /// /// Retrieve the modulus prime number Q of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in /// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// /// /// /// KP_G /// /// Retrieve the generator G of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in little-endian /// form. The pdwDataLen parameter contains the size of the buffer, in bytes. /// /// /// /// /// If a block cipher session key is specified by the hKey parameter, the dwParam value can also be set to one of the following values. /// /// /// /// Value /// Meaning /// /// /// KP_EFFECTIVE_KEYLEN /// /// Retrieve the effective key length of an RC2 key. The pbData parameter is a pointer to a DWORD value that receives the effective /// key length. /// /// /// /// KP_IV /// /// Retrieve the initialization vector of the key. The pbData parameter is a pointer to a BYTE array that receives the /// initialization vector. The size of this array is the block size, in bytes. For example, if the block length is 64 bits, the /// initialization vector consists of 8 bytes. /// /// /// /// KP_PADDING /// /// Retrieve the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that identifies /// the padding method used by the cipher. This can be one of the following values. PKCS5_PADDING Specifies the PKCS 5 (sec 6.2) /// padding method. RANDOM_PADDING The padding uses random numbers. This padding method is not supported by the Microsoft supplied /// CSPs. ZERO_PADDING The padding uses zeros. This padding method is not supported by the Microsoft supplied CSPs. /// /// /// /// KP_MODE /// /// Retrieve the cipher mode. The pbData parameter is a pointer to a DWORD value that receives a cipher mode identifier. For more /// information about cipher modes, see Data Encryption and Decryption. The following cipher mode identifiers are currently defined. /// CRYPT_MODE_CBC The cipher mode is cipher block chaining. CRYPT_MODE_CFB The cipher mode is cipher feedback (CFB). Microsoft CSPs /// currently support only 8-bit feedback in cipher feedback mode. CRYPT_MODE_ECB The cipher mode is electronic codebook. /// CRYPT_MODE_OFB The cipher mode is Output Feedback (OFB). Microsoft CSPs currently do not support Output Feedback Mode. /// CRYPT_MODE_CTS The cipher mode is ciphertext stealing mode. /// /// /// /// KP_MODE_BITS /// /// Retrieve the number of bits to feed back. The pbData parameter is a pointer to a DWORD value that receives the number of bits /// that are processed per cycle when the OFB or CFB cipher modes are used. /// /// /// /// /// If a Diffie-Hellman algorithm or Digital Signature Algorithm (DSA) key is specified by hKey, the dwParam value can also be set /// to the following value. /// /// /// /// Value /// Meaning /// /// /// KP_VERIFY_PARAMS /// /// Verifies the parameters of a Diffie-Hellman algorithm or DSA key. The pbData parameter is not used, and the value pointed to by /// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise. /// /// /// /// KP_KEYVAL /// /// This value is not used. Windows Vista, Windows Server 2003 and Windows XP: Retrieve the secret agreement value from an imported /// Diffie-Hellman algorithm key of type CALG_AGREEDKEY_ANY. The pbData parameter is the address of a buffer that receives the /// secret agreement value, in little-endian format. This buffer must be the same length as the key. The dwFlags parameter must be /// set to 0xF42A19B6. This property can only be retrieved by a thread running under the local system account.This property is /// available for use in the operating systems listed above. It may be altered or unavailable in subsequent versions. /// /// /// /// If a certificate is specified by hKey, the dwParam value can also be set to the following value. /// /// /// Value /// Meaning /// /// /// KP_CERTIFICATE /// /// A buffer that contains the DER-encoded X.509 certificate. The pbData parameter is not used, and the value pointed to by /// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise. /// /// /// /// /// The specified value data. The form of this data varies, depending on the value number. public static T CryptGetKeyParam(HCRYPTKEY hKey, KeyParam dwParam) => CryptGetValue(CryptGetKeyParam, hKey, dwParam); /// /// The CryptGetProvParam function retrieves parameters that govern the operations of a cryptographic service provider (CSP). /// /// /// A handle of the CSP target of the query. This handle must have been created by using the CryptAcquireContext function. /// /// /// The nature of the query. The following queries are defined. /// /// /// Value /// Meaning /// /// /// PP_ADMIN_PIN 31 (0x1F) /// Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR. /// /// /// PP_APPLI_CERT 18 (0x12) /// This constant is not used. /// /// /// PP_CHANGE_PASSWORD 7 (0x7) /// This constant is not used. /// /// /// PP_CERTCHAIN 9 (0x9) /// Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded. /// /// /// PP_CONTAINER 6 (0x6) /// /// The name of the current key container as a null-terminated CHAR string. This string is exactly the same as the one passed in the /// pszContainer parameter of the CryptAcquireContext function to specify the key container to use. The pszContainer parameter can /// be read to determine the name of the default key container. /// /// /// /// PP_CRYPT_COUNT_KEY_USE 41 (0x29) /// Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. Windows XP: This parameter is not supported. /// /// /// PP_ENUMALGS 1 (0x1) /// /// A PROV_ENUMALGS structure that contains information about one algorithm supported by the CSP being queried. The first time this /// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first /// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags /// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This /// function is not thread safe, and all of the available algorithms might not be enumerated if this function is used in a /// multithreaded context. /// /// /// /// PP_ENUMALGS_EX 22 (0x16) /// /// A PROV_ENUMALGS_EX structure that contains information about one algorithm supported by the CSP being queried. The structure /// returned contains more information about the algorithm than the structure returned for PP_ENUMALGS. The first time this value is /// read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first element in /// the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags parameter. When /// this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This function is not /// thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context. /// /// /// /// PP_ENUMCONTAINERS 2 (0x2) /// /// The name of one of the key containers maintained by the CSP in the form of a null-terminated CHAR string. The first time this /// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first /// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags /// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. To /// enumerate key containers associated with a computer, first call CryptAcquireContext using the CRYPT_MACHINE_KEYSET flag, and /// then use the handle returned from CryptAcquireContext as the hProv parameter in the call to CryptGetProvParam. This function is /// not thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context. /// /// /// /// PP_ENUMELECTROOTS 26 (0x1A) /// This constant is not used. /// /// /// PP_ENUMEX_SIGNING_PROT 40 (0x28) /// /// Indicates that the current CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function succeeds, the /// CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function fails with an NTE_BAD_TYPE error code, /// the CSP does not support the dwProtocols member. /// /// /// /// PP_ENUMMANDROOTS 25 (0x19) /// This constant is not used. /// /// /// PP_IMPTYPE 3 (0x3) /// A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks. /// /// /// PP_KEY_TYPE_SUBTYPE 10 (0xA) /// This query is not used. /// /// /// PP_KEYEXCHANGE_PIN 32 (0x20) /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. /// /// /// PP_KEYSET_SEC_DESCR 8 (0x8) /// /// Retrieves the security descriptor for the key storage container. The pbData parameter is the address of a SECURITY_DESCRIPTOR /// structure that receives the security descriptor for the key storage container. The security descriptor is returned in /// self-relative format. /// /// /// /// PP_KEYSET_TYPE 27 (0x1B) /// /// Determines whether the hProv parameter is a computer key set. The pbData parameter must be a DWORD; the DWORD will be set to the /// CRYPT_MACHINE_KEYSET flag if that flag was passed to the CryptAcquireContext function. /// /// /// /// PP_KEYSPEC 39 (0x27) /// /// Returns information about the key specifier values that the CSP supports. Key specifier values are joined in a logical OR and /// returned in the pbData parameter of the call as a DWORD. For example, the Microsoft Base Cryptographic Provider version 1.0 /// returns a DWORD value of AT_SIGNATURE | AT_KEYEXCHANGE. /// /// /// /// PP_KEYSTORAGE 17 (0x11) /// Returns a DWORD value of CRYPT_SEC_DESCR. /// /// /// PP_KEYX_KEYSIZE_INC 35 (0x23) /// /// The number of bits for the increment length of AT_KEYEXCHANGE. This information is used with information returned in the /// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_KEYX_KEYSIZE_INC, the valid key lengths for /// AT_KEYEXCHANGE can be determined. These key lengths can then be used with CryptGenKey. For example if a CSP enumerates /// CALG_RSA_KEYX (AT_KEYEXCHANGE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment /// length as 64 bits, then valid key lengths are 512, 576, 640,… 1024. /// /// /// /// PP_NAME 4 (0x4) /// /// The name of the CSP in the form of a null-terminated CHAR string. This string is identical to the one passed in the pszProvider /// parameter of the CryptAcquireContext function to specify that the current CSP be used. /// /// /// /// PP_PROVTYPE 16 (0x10) /// A DWORD value that indicates the provider type of the CSP. /// /// /// PP_ROOT_CERTSTORE 46 (0x2E) /// /// Obtains the root certificate store for the smart card. This certificate store contains all of the root certificates that are /// stored on the smart card. The pbData parameter is the address of an HCERTSTORE variable that receives the handle of the /// certificate store. When this handle is no longer needed, the caller must close it by using the CertCloseStore function. Windows /// Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// PP_SESSION_KEYSIZE 20 (0x14) /// The size, in bits, of the session key. /// /// /// PP_SGC_INFO 37 (0x25) /// Used with server gated cryptography. /// /// /// PP_SIG_KEYSIZE_INC 34 (0x22) /// /// The number of bits for the increment length of AT_SIGNATURE. This information is used with information returned in the /// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_SIG_KEYSIZE_INC, the valid key lengths for /// AT_SIGNATURE can be determined. These key lengths can then be used with CryptGenKey. For example, if a CSP enumerates /// CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment length /// as 64 bits, then valid key lengths are 512, 576, 640,… 1024. /// /// /// /// PP_SIGNATURE_PIN 33 (0x21) /// Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. /// /// /// PP_SMARTCARD_GUID 45 (0x2D) /// /// Obtains the identifier of the smart card. The pbData parameter is the address of a GUID structure that receives the identifier /// of the smart card. Windows Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// PP_SMARTCARD_READER 43 (0x2B) /// /// Obtains the name of the smart card reader. The pbData parameter is the address of an ANSI character array that receives a /// null-terminated ANSI string that contains the name of the smart card reader. The size of this buffer, contained in the variable /// pointed to by the pdwDataLen parameter, must include the NULL terminator. Windows Server 2003 and Windows XP: This parameter is /// not supported. /// /// /// /// PP_SYM_KEYSIZE 19 (0x13) /// The size of the symmetric key. /// /// /// PP_UI_PROMPT 21 (0x15) /// This query is not used. /// /// /// PP_UNIQUE_CONTAINER 36 (0x24) /// /// The unique container name of the current key container in the form of a null-terminated CHAR string. For many CSPs, this name is /// the same name returned when the PP_CONTAINER value is used. The CryptAcquireContext function must work with this container name. /// /// /// /// PP_USE_HARDWARE_RNG 38 (0x26) /// /// Indicates whether a hardware random number generator (RNG) is supported. When PP_USE_HARDWARE_RNG is specified, the function /// succeeds and returns TRUE if a hardware RNG is supported. The function fails and returns FALSE if a hardware RNG is not /// supported. If a RNG is supported, PP_USE_HARDWARE_RNG can be set in CryptSetProvParam to indicate that the CSP must exclusively /// use the hardware RNG for this provider context. When PP_USE_HARDWARE_RNG is used, the pbData parameter must be NULL and dwFlags /// must be zero. None of the Microsoft CSPs currently support using a hardware RNG. /// /// /// /// PP_USER_CERTSTORE 42 (0x2A) /// /// Obtains the user certificate store for the smart card. This certificate store contains all of the user certificates that are /// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING encoding /// and should contain the CERT_KEY_PROV_INFO_PROP_ID property. The pbData parameter is the address of an HCERTSTORE variable that /// receives the handle of an in-memory certificate store. When this handle is no longer needed, the caller must close it by using /// the CertCloseStore function. Windows Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// PP_VERSION 5 (0x5) /// /// The version number of the CSP. The least significant byte contains the minor version number and the next most significant byte /// the major version number. Version 2.0 is represented as 0x00000200. To maintain backward compatibility with earlier versions of /// the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the provider names retain the /// "v1.0" designation in later versions. /// /// /// /// /// /// /// A pointer to a buffer to receive the data. The form of this data varies depending on the value of dwParam. When dwParam is set /// to PP_USE_HARDWARE_RNG, pbData must be set to NULL. /// /// /// This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see /// Retrieving Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value that specifies the size, in bytes, of the buffer pointed to by the pbData parameter. When the /// function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually /// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to /// by this parameter is updated to reflect the actual size of the data copied to the buffer. If PP_ENUMALGS, or PP_ENUMALGS_EX is /// set, the pdwDataLen parameter works somewhat differently. If pbData is NULL or the value pointed to by pdwDataLen is too /// small, the value returned in this parameter is the size of the largest item in the enumeration list instead of the size of the /// item currently being read. If PP_ENUMCONTAINERS is set, the first call to the function returns the size of the maximum /// key-container allowed by the current provider. This is in contrast to other possible behaviors, like returning the length of the /// longest existing container, or the length of the current container. Subsequent enumerating calls will not change the dwLen /// parameter. For each enumerated container, the caller can determine the length of the null-terminated string /// programmatically, if desired. If one of the enumeration values is read and the pbData parameter is NULL, the CRYPT_FIRST /// flag must be specified for the size information to be correctly retrieved. /// /// /// /// /// If dwParam is PP_KEYSET_SEC_DESCR, the security descriptor on the key container where the keys are stored is retrieved. /// For this case, dwFlags is used to pass in the SECURITY_INFORMATION bit flags that indicate the requested security /// information, as defined in the Platform SDK. SECURITY_INFORMATION bit flags can be combined with a bitwise- OR operation. /// /// The following values are defined for use with PP_KEYSET_SEC_DESCR. /// /// /// Value /// Meaning /// /// /// OWNER_SECURITY_INFORMATION /// Owner identifier of the object is being referenced. /// /// /// GROUP_SECURITY_INFORMATION /// Primary group identifier of the object is being referenced. /// /// /// DACL_SECURITY_INFORMATION /// Discretionary ACL of the object is being referenced. /// /// /// SACL_SECURITY_INFORMATION /// System ACL of the object is being referenced. /// /// /// The following values are defined for use with PP_ENUMALGS, PP_ENUMALGS_EX, and PP_ENUMCONTAINERS. /// /// /// Value /// Meaning /// /// /// CRYPT_FIRST 1 (0x1) /// Retrieve the first element in the enumeration. This has the same effect as resetting the enumerator. /// /// /// CRYPT_NEXT 2 (0x2) /// /// Retrieve the next element in the enumeration. When there are no more elements to retrieve, this function will fail and set the /// last error to ERROR_NO_MORE_ITEMS. /// /// /// /// CRYPT_SGC_ENUM 4 (0x4) /// /// Retrieve server-gated cryptography (SGC) enabled certificates. SGC enabled certificates are no longer supported. For more /// information, see Microsoft Support Article 875450. /// /// /// /// CRYPT_SGC /// This flag is not used. /// /// /// CRYPT_FASTSGC /// This flag is not used. /// /// /// /// /// If the function succeeds, the return value is nonzero ( TRUE). /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_MORE_DATA /// /// If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the /// ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen. /// /// /// /// ERROR_NO_MORE_ITEMS /// /// The end of the enumeration list has been reached. No valid data has been placed in the pbData buffer. This error code is /// returned only when dwParam equals PP_ENUMALGS or PP_ENUMCONTAINERS. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter specifies a flag that is not valid. /// /// /// NTE_BAD_TYPE /// The dwParam parameter specifies an unknown value number. /// /// /// NTE_BAD_UID /// The CSP context specified by hProv is not valid. /// /// /// /// /// This function must not be used on a thread of a multithreaded program. /// The following values are returned in pbData if dwParam is PP_IMPTYPE. /// /// /// Value /// Meaning /// /// /// CRYPT_IMPL_HARDWARE1 /// Implementation is in hardware. /// /// /// CRYPT_IMPL_SOFTWARE2 /// Implementation is in software. /// /// /// CRYPT_IMPL_MIXED3 /// Implementation involves both hardware and software. /// /// /// CRYPT_IMPL_UNKNOWN4 /// Implementation type is unknown. /// /// /// CRYPT_IMPL_REMOVABLE8 /// Implementation is in removable media. /// /// /// /// The dwFlags parameter is used to pass in the SECURITY_INFORMATION bit flags that indicate the requested security /// information. The pointer to the security descriptor is returned in the pbData parameter and the length of the security /// descriptor is returned in the pdwDataLen parameter. Key-container security is handled with SetFileSecurity and GetFileSecurity. /// /// /// The class of an algorithm enumerated with dwParam set to PP_ENUMALGS or PP_ENUMALGS_EX can be determined. This might be done to /// display a list of encryption algorithms supported and to disregard the rest. The GET_ALG_CLASS( x ) macro takes an /// algorithm identifier as an argument and returns a code indicating the general class of that algorithm. Possible return values include: /// /// /// /// ALG_CLASS_DATA_ENCRYPT /// /// /// ALG_CLASS_HASH /// /// /// ALG_CLASS_KEY_EXCHANGE /// /// /// ALG_CLASS_SIGNATURE /// /// /// /// The following table lists the algorithms supported by the Microsoft Base Cryptographic Provider along with the class of each algorithm. /// /// /// /// Name /// Identifier /// Class /// /// /// "MD2" /// CALG_MD2 /// ALG_CLASS_HASH /// /// /// "MD5" /// CALG_MD5 /// ALG_CLASS_HASH /// /// /// "SHA" /// CALG_SHA /// ALG_CLASS_HASH /// /// /// "MAC" /// CALG_MAC /// ALG_CLASS_HASH /// /// /// "RSA_SIGN" /// CALG_RSA_SIGN /// ALG_CLASS_SIGNATURE /// /// /// "RSA_KEYX" /// CALG_RSA_KEYX /// ALG_CLASS_KEY_EXCHANGE /// /// /// "RC2" /// CALG_RC2 /// ALG_CLASS_DATA_ENCRYPT /// /// /// "RC4" /// CALG_RC4 /// ALG_CLASS_DATA_ENCRYPT /// /// /// /// Applications must not use an algorithm with an algorithm identifier that is not recognized. Using an unknown cryptographic /// algorithm can produce unpredictable results. /// /// Examples /// /// The following example shows finding the name of the CSP associated with a cryptographic service provider handle and the name of /// the key container associated with the handle. For the complete context for this example, see Example C Program: Using CryptAcquireContext. /// /// For another example that uses this function, see Example C Program: Enumerating CSP Providers and Provider Types. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetprovparam BOOL CryptGetProvParam( HCRYPTPROV // hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "c0b7c1c8-aa42-4d40-a7f7-99c0821c8977")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptGetProvParam(HCRYPTPROV hProv, ProvParam dwParam, [Out, Optional] IntPtr pbData, ref uint pdwDataLen, uint dwFlags); /// /// The CryptGetProvParam function retrieves parameters that govern the operations of a cryptographic service provider (CSP). /// /// The expected return type. /// /// A handle of the CSP target of the query. This handle must have been created by using the CryptAcquireContext function. /// /// /// The nature of the query. The following queries are defined. /// /// /// Value /// Meaning /// /// /// PP_ADMIN_PIN 31 (0x1F) /// Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR. /// /// /// PP_APPLI_CERT 18 (0x12) /// This constant is not used. /// /// /// PP_CHANGE_PASSWORD 7 (0x7) /// This constant is not used. /// /// /// PP_CERTCHAIN 9 (0x9) /// Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded. /// /// /// PP_CONTAINER 6 (0x6) /// /// The name of the current key container as a null-terminated CHAR string. This string is exactly the same as the one passed in the /// pszContainer parameter of the CryptAcquireContext function to specify the key container to use. The pszContainer parameter can /// be read to determine the name of the default key container. /// /// /// /// PP_CRYPT_COUNT_KEY_USE 41 (0x29) /// Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. Windows XP: This parameter is not supported. /// /// /// PP_ENUMALGS 1 (0x1) /// /// A PROV_ENUMALGS structure that contains information about one algorithm supported by the CSP being queried. The first time this /// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first /// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags /// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This /// function is not thread safe, and all of the available algorithms might not be enumerated if this function is used in a /// multithreaded context. /// /// /// /// PP_ENUMALGS_EX 22 (0x16) /// /// A PROV_ENUMALGS_EX structure that contains information about one algorithm supported by the CSP being queried. The structure /// returned contains more information about the algorithm than the structure returned for PP_ENUMALGS. The first time this value is /// read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first element in /// the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags parameter. When /// this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This function is not /// thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context. /// /// /// /// PP_ENUMCONTAINERS 2 (0x2) /// /// The name of one of the key containers maintained by the CSP in the form of a null-terminated CHAR string. The first time this /// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first /// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags /// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. To /// enumerate key containers associated with a computer, first call CryptAcquireContext using the CRYPT_MACHINE_KEYSET flag, and /// then use the handle returned from CryptAcquireContext as the hProv parameter in the call to CryptGetProvParam. This function is /// not thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context. /// /// /// /// PP_ENUMELECTROOTS 26 (0x1A) /// This constant is not used. /// /// /// PP_ENUMEX_SIGNING_PROT 40 (0x28) /// /// Indicates that the current CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function succeeds, the /// CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function fails with an NTE_BAD_TYPE error code, /// the CSP does not support the dwProtocols member. /// /// /// /// PP_ENUMMANDROOTS 25 (0x19) /// This constant is not used. /// /// /// PP_IMPTYPE 3 (0x3) /// A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks. /// /// /// PP_KEY_TYPE_SUBTYPE 10 (0xA) /// This query is not used. /// /// /// PP_KEYEXCHANGE_PIN 32 (0x20) /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. /// /// /// PP_KEYSET_SEC_DESCR 8 (0x8) /// /// Retrieves the security descriptor for the key storage container. The pbData parameter is the address of a SECURITY_DESCRIPTOR /// structure that receives the security descriptor for the key storage container. The security descriptor is returned in /// self-relative format. /// /// /// /// PP_KEYSET_TYPE 27 (0x1B) /// /// Determines whether the hProv parameter is a computer key set. The pbData parameter must be a DWORD; the DWORD will be set to the /// CRYPT_MACHINE_KEYSET flag if that flag was passed to the CryptAcquireContext function. /// /// /// /// PP_KEYSPEC 39 (0x27) /// /// Returns information about the key specifier values that the CSP supports. Key specifier values are joined in a logical OR and /// returned in the pbData parameter of the call as a DWORD. For example, the Microsoft Base Cryptographic Provider version 1.0 /// returns a DWORD value of AT_SIGNATURE | AT_KEYEXCHANGE. /// /// /// /// PP_KEYSTORAGE 17 (0x11) /// Returns a DWORD value of CRYPT_SEC_DESCR. /// /// /// PP_KEYX_KEYSIZE_INC 35 (0x23) /// /// The number of bits for the increment length of AT_KEYEXCHANGE. This information is used with information returned in the /// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_KEYX_KEYSIZE_INC, the valid key lengths for /// AT_KEYEXCHANGE can be determined. These key lengths can then be used with CryptGenKey. For example if a CSP enumerates /// CALG_RSA_KEYX (AT_KEYEXCHANGE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment /// length as 64 bits, then valid key lengths are 512, 576, 640,… 1024. /// /// /// /// PP_NAME 4 (0x4) /// /// The name of the CSP in the form of a null-terminated CHAR string. This string is identical to the one passed in the pszProvider /// parameter of the CryptAcquireContext function to specify that the current CSP be used. /// /// /// /// PP_PROVTYPE 16 (0x10) /// A DWORD value that indicates the provider type of the CSP. /// /// /// PP_ROOT_CERTSTORE 46 (0x2E) /// /// Obtains the root certificate store for the smart card. This certificate store contains all of the root certificates that are /// stored on the smart card. The pbData parameter is the address of an HCERTSTORE variable that receives the handle of the /// certificate store. When this handle is no longer needed, the caller must close it by using the CertCloseStore function. Windows /// Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// PP_SESSION_KEYSIZE 20 (0x14) /// The size, in bits, of the session key. /// /// /// PP_SGC_INFO 37 (0x25) /// Used with server gated cryptography. /// /// /// PP_SIG_KEYSIZE_INC 34 (0x22) /// /// The number of bits for the increment length of AT_SIGNATURE. This information is used with information returned in the /// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_SIG_KEYSIZE_INC, the valid key lengths for /// AT_SIGNATURE can be determined. These key lengths can then be used with CryptGenKey. For example, if a CSP enumerates /// CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment length /// as 64 bits, then valid key lengths are 512, 576, 640,… 1024. /// /// /// /// PP_SIGNATURE_PIN 33 (0x21) /// Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. /// /// /// PP_SMARTCARD_GUID 45 (0x2D) /// /// Obtains the identifier of the smart card. The pbData parameter is the address of a GUID structure that receives the identifier /// of the smart card. Windows Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// PP_SMARTCARD_READER 43 (0x2B) /// /// Obtains the name of the smart card reader. The pbData parameter is the address of an ANSI character array that receives a /// null-terminated ANSI string that contains the name of the smart card reader. The size of this buffer, contained in the variable /// pointed to by the pdwDataLen parameter, must include the NULL terminator. Windows Server 2003 and Windows XP: This parameter is /// not supported. /// /// /// /// PP_SYM_KEYSIZE 19 (0x13) /// The size of the symmetric key. /// /// /// PP_UI_PROMPT 21 (0x15) /// This query is not used. /// /// /// PP_UNIQUE_CONTAINER 36 (0x24) /// /// The unique container name of the current key container in the form of a null-terminated CHAR string. For many CSPs, this name is /// the same name returned when the PP_CONTAINER value is used. The CryptAcquireContext function must work with this container name. /// /// /// /// PP_USE_HARDWARE_RNG 38 (0x26) /// /// Indicates whether a hardware random number generator (RNG) is supported. When PP_USE_HARDWARE_RNG is specified, the function /// succeeds and returns TRUE if a hardware RNG is supported. The function fails and returns FALSE if a hardware RNG is not /// supported. If a RNG is supported, PP_USE_HARDWARE_RNG can be set in CryptSetProvParam to indicate that the CSP must exclusively /// use the hardware RNG for this provider context. When PP_USE_HARDWARE_RNG is used, the pbData parameter must be NULL and dwFlags /// must be zero. None of the Microsoft CSPs currently support using a hardware RNG. /// /// /// /// PP_USER_CERTSTORE 42 (0x2A) /// /// Obtains the user certificate store for the smart card. This certificate store contains all of the user certificates that are /// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING encoding /// and should contain the CERT_KEY_PROV_INFO_PROP_ID property. The pbData parameter is the address of an HCERTSTORE variable that /// receives the handle of an in-memory certificate store. When this handle is no longer needed, the caller must close it by using /// the CertCloseStore function. Windows Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// PP_VERSION 5 (0x5) /// /// The version number of the CSP. The least significant byte contains the minor version number and the next most significant byte /// the major version number. Version 2.0 is represented as 0x00000200. To maintain backward compatibility with earlier versions of /// the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the provider names retain the /// "v1.0" designation in later versions. /// /// /// /// /// /// /// If dwParam is PP_KEYSET_SEC_DESCR, the security descriptor on the key container where the keys are stored is retrieved. /// For this case, dwFlags is used to pass in the SECURITY_INFORMATION bit flags that indicate the requested security /// information, as defined in the Platform SDK. SECURITY_INFORMATION bit flags can be combined with a bitwise- OR operation. /// /// The following values are defined for use with PP_KEYSET_SEC_DESCR. /// /// /// Value /// Meaning /// /// /// OWNER_SECURITY_INFORMATION /// Owner identifier of the object is being referenced. /// /// /// GROUP_SECURITY_INFORMATION /// Primary group identifier of the object is being referenced. /// /// /// DACL_SECURITY_INFORMATION /// Discretionary ACL of the object is being referenced. /// /// /// SACL_SECURITY_INFORMATION /// System ACL of the object is being referenced. /// /// /// The following values are defined for use with PP_ENUMALGS, PP_ENUMALGS_EX, and PP_ENUMCONTAINERS. /// /// /// Value /// Meaning /// /// /// CRYPT_FIRST 1 (0x1) /// Retrieve the first element in the enumeration. This has the same effect as resetting the enumerator. /// /// /// CRYPT_NEXT 2 (0x2) /// /// Retrieve the next element in the enumeration. When there are no more elements to retrieve, this function will fail and set the /// last error to ERROR_NO_MORE_ITEMS. /// /// /// /// CRYPT_SGC_ENUM 4 (0x4) /// /// Retrieve server-gated cryptography (SGC) enabled certificates. SGC enabled certificates are no longer supported. For more /// information, see Microsoft Support Article 875450. /// /// /// /// CRYPT_SGC /// This flag is not used. /// /// /// CRYPT_FASTSGC /// This flag is not used. /// /// /// /// The specified value data. The form of this data varies, depending on the value number. public static T CryptGetProvParam(HCRYPTPROV hProv, ProvParam dwParam, uint dwFlags) => CryptGetValue(CryptGetProvParam, hProv, dwParam, dwFlags); /// /// The CryptGetUserKey function retrieves a handle of one of a user's two public/private key pairs. This function is used only by /// the owner of the public/private key pairs and only when the handle of a cryptographic service provider (CSP) and its associated /// key container is available. If the CSP handle is not available and the user's certificate is, use CryptAcquireCertificatePrivateKey. /// /// HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext. /// /// Identifies the private key to use from the key container. It can be AT_KEYEXCHANGE or AT_SIGNATURE. /// /// Additionally, some providers allow access to other user-specific keys through this function. For details, see the documentation /// on the specific provider. /// /// /// /// A pointer to the HCRYPTKEY handle of the retrieved keys. When you have finished using the key, delete the handle by calling the /// CryptDestroyKey function. /// /// /// If the function succeeds, the return value is nonzero (TRUE). /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_KEY /// The dwKeySpec parameter contains a value that is not valid. /// /// /// NTE_BAD_UID /// The hProv parameter does not contain a valid context handle. /// /// /// NTE_NO_KEY /// The key requested by the dwKeySpec parameter does not exist. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetuserkey // BOOL CryptGetUserKey( HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "d9166b98-e5f1-4e5c-b6f1-2a086b102e0f")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptGetUserKey(HCRYPTPROV hProv, CertKeySpec dwKeySpec, out SafeHCRYPTKEY phUserKey); /// /// The CryptHashData function adds data to a specified hash object. This function and CryptHashSessionKey can be called multiple /// times to compute the hash of long or discontinuous data streams. /// Before calling this function, CryptCreateHash must be called to create a handle of a hash object. /// /// Handle of the hash object. /// A pointer to a buffer that contains the data to be added to the hash object. /// Number of bytes of data to be added. This must be zero if the CRYPT_USERDATA flag is set. /// /// The following flag values are defined. /// /// /// Value /// Meaning /// /// /// CRYPT_OWF_REPL_LM_HASH 0x00000001 /// This flag is not used. /// /// /// CRYPT_USERDATA 1 (0x1) /// /// All Microsoft Cryptographic Providers ignore this parameter. For any CSP that does not ignore this parameter, if this flag is /// set, the CSP prompts the user to input data directly. This data is added to the hash. The application is not allowed access to /// the data. This flag can be used to allow the user to enter a PIN into the system. /// /// /// /// /// /// If the function succeeds, the return value is TRUE. /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The hHash handle specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter contains a value that is not valid. /// /// /// NTE_BAD_HASH /// The hash object specified by the hHash parameter is not valid. /// /// /// NTE_BAD_HASH_STATE /// An attempt was made to add data to a hash object that is already marked "finished." /// /// /// NTE_BAD_KEY /// /// A keyed hash algorithm is being used, but the session key is no longer valid. This error is generated if the session key is /// destroyed before the hashing operation is complete. /// /// /// /// NTE_BAD_LEN /// The CSP does not ignore the CRYPT_USERDATA flag, the flag is set, and the dwDataLen parameter has a nonzero value. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hash object was created cannot be found. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// NTE_NO_MEMORY /// The CSP ran out of memory during the operation. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-crypthashdata BOOL CryptHashData( HCRYPTHASH hHash, const // BYTE *pbData, DWORD dwDataLen, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "ec1482a2-c2cb-4c5f-af9c-d493134413d6")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptHashData(HCRYPTHASH hHash, [In] IntPtr pbData, uint dwDataLen, uint dwFlags); /// /// The CryptHashSessionKey function computes the cryptographic hash of a session key object. This function can be called multiple /// times with the same hash handle to compute the hash of multiple keys. Calls to CryptHashSessionKey can be interspersed with /// calls to CryptHashData. /// Before calling this function, CryptCreateHash must be called to create the handle of a hash object. /// /// A handle to the hash object. /// A handle to the key object to be hashed. /// /// The following flag value is defined. /// /// /// Value /// Meaning /// /// /// CRYPT_LITTLE_ENDIAN 0x00000001 /// /// When this flag is set, the bytes of the key are hashed in little-endian form. Note that by default (when dwFlags is zero), the /// bytes of the key are hashed in big-endian form. /// /// /// /// /// /// If the function succeeds, the return value is TRUE. /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The hHash handle specifies an algorithm that this CSP does not support. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hash object specified by the hHash parameter is not valid. /// /// /// NTE_BAD_HASH_STATE /// An attempt was made to add data to a hash object that is already marked "finished." /// /// /// NTE_BAD_KEY /// /// A keyed hash algorithm is being used, but the session key is no longer valid. This error is generated if the session key is /// destroyed before the hashing operation is complete. /// /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hash object was created cannot be found. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-crypthashsessionkey BOOL CryptHashSessionKey( HCRYPTHASH // hHash, HCRYPTKEY hKey, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "75781993-7faf-4149-80cc-ae50dbd4de2a")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptHashSessionKey(HCRYPTHASH hHash, HCRYPTKEY hKey, CryptHashSessionKeyFlags dwFlags); /// /// The CryptImportKey function transfers a cryptographic key from a key BLOB into a cryptographic service provider (CSP). This /// function can be used to import an Schannel session key, regular session key, public key, or public/private key pair. For all but /// the public key, the key or key pair is encrypted. /// /// The handle of a CSP obtained with the CryptAcquireContext function. /// /// A BYTE array that contains a PUBLICKEYSTRUC BLOB header followed by the encrypted key. This key BLOB is created by the /// CryptExportKey function, either in this application or by another application possibly running on a different computer. /// /// Contains the length, in bytes, of the key BLOB. /// /// /// A handle to the cryptographic key that decrypts the key stored in pbData. This key must come from the same CSP to which hProv /// refers. The meaning of this parameter differs depending on the CSP type and the type of key BLOB being imported: /// /// /// /// /// If the key BLOB is encrypted with the key exchange key pair, for example, a SIMPLEBLOB, this parameter can be the handle /// to the key exchange key. /// /// /// /// /// If the key BLOB is encrypted with a session key, for example, an encrypted PRIVATEKEYBLOB, this parameter contains the /// handle of this session key. /// /// /// /// If the key BLOB is not encrypted, for example, a PUBLICKEYBLOB, this parameter is not used and must be zero. /// /// /// /// If the key BLOB is encrypted with a session key in an Schannel CSP, for example, an encrypted OPAQUEKEYBLOB or any other /// vendor-specific OPAQUEKEYBLOB, this parameter is not used and must be set to zero. /// /// /// /// /// Note Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for /// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished /// using the handle, release it by calling the CryptDestroyKey function. /// /// /// /// Currently used only when a public/private key pair in the form of a PRIVATEKEYBLOB is imported into the CSP. /// This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// CRYPT_EXPORTABLE /// /// The key being imported is eventually to be reexported. If this flag is not used, then calls to CryptExportKey with the key /// handle fail. /// /// /// /// CRYPT_OAEP /// This flag causes PKCS #1 version 2 formatting to be checked with RSA encryption and decryption when importing SIMPLEBLOBs. /// /// /// CRYPT_NO_SALT /// A no-salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. /// /// /// CRYPT_USER_PROTECTED /// /// If this flag is set, the CSP notifies the user through a dialog box or some other method when certain actions are attempted /// using this key. The precise behavior is specified by the CSP or the CSP type used. If the provider context was acquired with /// CRYPT_SILENT set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT. /// /// /// /// CRYPT_IPSEC_HMAC_KEY /// /// Allows for the import of an RC2 key that is larger than 16 bytes. If this flag is not set, calls to the CryptImportKey function /// with RC2 keys that are greater than 16 bytes fail, and a call to GetLastError will return NTE_BAD_DATA. /// /// /// /// /// /// A pointer to a HCRYPTKEY value that receives the handle of the imported key. When you have finished using the key, /// release the handle by calling the CryptDestroyKey function. /// /// /// If the function succeeds, the function returns nonzero. /// If the function fails, it returns zero. For extended error information, call GetLastError. /// Error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_BUSY /// Some CSPs set this error if a private key is imported into a container while another thread or process is using this key. /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The simple key BLOB to be imported is not encrypted with the expected key exchange algorithm. /// /// /// NTE_BAD_DATA /// /// Either the algorithm that works with the public key to be imported is not supported by this CSP, or an attempt was made to /// import a session key that was encrypted with something other than one of your public keys. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter specified is not valid. /// /// /// NTE_BAD_TYPE /// The key BLOB type is not supported by this CSP and is possibly not valid. /// /// /// NTE_BAD_UID /// The hProv parameter does not contain a valid context handle. /// /// /// NTE_BAD_VER /// The version number of the key BLOB does not match the CSP version. This usually indicates that the CSP needs to be upgraded. /// /// /// /// /// /// When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify the imported key as a /// PLAINTEXTKEYBLOB type and set the appropriate algorithm identifier in the aiKeyAlg field of the PUBLICKEYSTRUC /// BLOB header. /// /// /// The CryptImportKey function can be used to import a plaintext key for symmetric algorithms; however, we recommend that, /// for ease of use, you use the CryptGenKey function instead. When you import a plaintext key, the structure of the key BLOB that /// is passed in the pbData parameter is a PLAINTEXTKEYBLOB. /// /// You can use the PLAINTEXTKEYBLOB type with any algorithm or type of key combination supported by the CSP in use. /// For an example of importing a plaintext key, see Example C Program: Importing a Plaintext Key. /// The following example shows how you can set the header fields. /// The length of the key is specified in keyBlob.keyLength, which is followed by the actual key data. /// /// Note The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. CRYPT_IPSEC_HMAC_KEY /// allows the import of RC2 keys longer than 16 bytes. /// /// /// For any of the Data Encryption Standard (DES) key permutations that use PLAINTEXTKEYBLOB, only the full key size, /// including parity bit, can be imported. /// /// The following key sizes are supported. /// /// /// Algorithm /// Supported key size /// /// /// CALG_DES /// 64 bits /// /// /// CALG_3DES_112 /// 128 bits /// /// /// CALG_3DES /// 192 bits /// /// /// Examples /// /// The following example shows how to import a key from a key BLOB. For a full example for this function, see Example C Program: /// Signing a Hash and Verifying the Hash Signature. For additional code that uses this function, see Example C Program: Decrypting /// a File. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptimportkey BOOL CryptImportKey( HCRYPTPROV hProv, // const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "f48b6ec9-e03b-43b0-9f22-120ae93d934c")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptImportKey(HCRYPTPROV hProv, [In] IntPtr pbData, uint dwDataLen, HCRYPTKEY hPubKey, uint dwFlags, out SafeHCRYPTKEY phKey); /// /// The CryptImportKey function transfers a cryptographic key from a key BLOB into a cryptographic service provider (CSP). This /// function can be used to import an Schannel session key, regular session key, public key, or public/private key pair. For all but /// the public key, the key or key pair is encrypted. /// /// The handle of a CSP obtained with the CryptAcquireContext function. /// /// A BYTE array that contains a PUBLICKEYSTRUC BLOB header followed by the encrypted key. This key BLOB is created by the /// CryptExportKey function, either in this application or by another application possibly running on a different computer. /// /// Contains the length, in bytes, of the key BLOB. /// /// /// A handle to the cryptographic key that decrypts the key stored in pbData. This key must come from the same CSP to which hProv /// refers. The meaning of this parameter differs depending on the CSP type and the type of key BLOB being imported: /// /// /// /// /// If the key BLOB is encrypted with the key exchange key pair, for example, a SIMPLEBLOB, this parameter can be the handle /// to the key exchange key. /// /// /// /// /// If the key BLOB is encrypted with a session key, for example, an encrypted PRIVATEKEYBLOB, this parameter contains the /// handle of this session key. /// /// /// /// If the key BLOB is not encrypted, for example, a PUBLICKEYBLOB, this parameter is not used and must be zero. /// /// /// /// If the key BLOB is encrypted with a session key in an Schannel CSP, for example, an encrypted OPAQUEKEYBLOB or any other /// vendor-specific OPAQUEKEYBLOB, this parameter is not used and must be set to zero. /// /// /// /// /// Note Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for /// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished /// using the handle, release it by calling the CryptDestroyKey function. /// /// /// /// Currently used only when a public/private key pair in the form of a PRIVATEKEYBLOB is imported into the CSP. /// This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// CRYPT_EXPORTABLE /// /// The key being imported is eventually to be reexported. If this flag is not used, then calls to CryptExportKey with the key /// handle fail. /// /// /// /// CRYPT_OAEP /// This flag causes PKCS #1 version 2 formatting to be checked with RSA encryption and decryption when importing SIMPLEBLOBs. /// /// /// CRYPT_NO_SALT /// A no-salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. /// /// /// CRYPT_USER_PROTECTED /// /// If this flag is set, the CSP notifies the user through a dialog box or some other method when certain actions are attempted /// using this key. The precise behavior is specified by the CSP or the CSP type used. If the provider context was acquired with /// CRYPT_SILENT set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT. /// /// /// /// CRYPT_IPSEC_HMAC_KEY /// /// Allows for the import of an RC2 key that is larger than 16 bytes. If this flag is not set, calls to the CryptImportKey function /// with RC2 keys that are greater than 16 bytes fail, and a call to GetLastError will return NTE_BAD_DATA. /// /// /// /// /// /// A pointer to a HCRYPTKEY value that receives the handle of the imported key. When you have finished using the key, /// release the handle by calling the CryptDestroyKey function. /// /// /// If the function succeeds, the function returns nonzero. /// If the function fails, it returns zero. For extended error information, call GetLastError. /// Error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_BUSY /// Some CSPs set this error if a private key is imported into a container while another thread or process is using this key. /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_ALGID /// The simple key BLOB to be imported is not encrypted with the expected key exchange algorithm. /// /// /// NTE_BAD_DATA /// /// Either the algorithm that works with the public key to be imported is not supported by this CSP, or an attempt was made to /// import a session key that was encrypted with something other than one of your public keys. /// /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter specified is not valid. /// /// /// NTE_BAD_TYPE /// The key BLOB type is not supported by this CSP and is possibly not valid. /// /// /// NTE_BAD_UID /// The hProv parameter does not contain a valid context handle. /// /// /// NTE_BAD_VER /// The version number of the key BLOB does not match the CSP version. This usually indicates that the CSP needs to be upgraded. /// /// /// /// /// /// When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify the imported key as a /// PLAINTEXTKEYBLOB type and set the appropriate algorithm identifier in the aiKeyAlg field of the PUBLICKEYSTRUC /// BLOB header. /// /// /// The CryptImportKey function can be used to import a plaintext key for symmetric algorithms; however, we recommend that, /// for ease of use, you use the CryptGenKey function instead. When you import a plaintext key, the structure of the key BLOB that /// is passed in the pbData parameter is a PLAINTEXTKEYBLOB. /// /// You can use the PLAINTEXTKEYBLOB type with any algorithm or type of key combination supported by the CSP in use. /// For an example of importing a plaintext key, see Example C Program: Importing a Plaintext Key. /// The following example shows how you can set the header fields. /// The length of the key is specified in keyBlob.keyLength, which is followed by the actual key data. /// /// Note The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. CRYPT_IPSEC_HMAC_KEY /// allows the import of RC2 keys longer than 16 bytes. /// /// /// For any of the Data Encryption Standard (DES) key permutations that use PLAINTEXTKEYBLOB, only the full key size, /// including parity bit, can be imported. /// /// The following key sizes are supported. /// /// /// Algorithm /// Supported key size /// /// /// CALG_DES /// 64 bits /// /// /// CALG_3DES_112 /// 128 bits /// /// /// CALG_3DES /// 192 bits /// /// /// Examples /// /// The following example shows how to import a key from a key BLOB. For a full example for this function, see Example C Program: /// Signing a Hash and Verifying the Hash Signature. For additional code that uses this function, see Example C Program: Decrypting /// a File. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptimportkey BOOL CryptImportKey( HCRYPTPROV hProv, // const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "f48b6ec9-e03b-43b0-9f22-120ae93d934c")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptImportKey(HCRYPTPROV hProv, [In] byte[] pbData, int dwDataLen, HCRYPTKEY hPubKey, uint dwFlags, out SafeHCRYPTKEY phKey); /// /// /// The CryptReleaseContext function releases the handle of a cryptographic service provider (CSP) and a key container. At each call /// to this function, the reference count on the CSP is reduced by one. When the reference count reaches zero, the context is fully /// released and it can no longer be used by any function in the application. /// /// /// An application calls this function after finishing the use of the CSP. After this function is called, the released CSP handle is /// no longer valid. This function does not destroy key containers or key pairs. /// /// /// Handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext. /// /// Reserved for future use and must be zero. If dwFlags is not set to zero, this function returns FALSE but the CSP is released. /// /// /// If the function succeeds, the return value is nonzero ( TRUE). /// /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. Some /// possible error codes are listed in the following table. /// /// /// /// Return code /// Description /// /// /// ERROR_BUSY /// The CSP context specified by hProv is currently being used by another process. /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_UID /// The hProv parameter does not contain a valid context handle. /// /// /// /// /// /// After this function has been called, the CSP session is finished and all existing session keys and hash objects created by using /// the hProv handle are no longer valid. In practice, all of these objects should be destroyed with calls to CryptDestroyKey and /// CryptDestroyHash before CryptReleaseContext is called. /// /// Examples /// For an example that uses this function, see Example C Program: Creating and Hashing a Session Key. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptreleasecontext BOOL CryptReleaseContext( HCRYPTPROV // hProv, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "c1e3e708-b543-4e87-8638-a9946a83e614")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptReleaseContext(HCRYPTPROV hProv, uint dwFlags = 0); /// /// The CryptSetHashParam function customizes the operations of a hash object, including setting up initial hash contents and /// selecting a specific hashing algorithm. /// /// A handle to the hash object on which to set parameters. /// /// This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// HP_HMAC_INFO. /// /// A pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used. /// /// /// /// HP_HASHVAL. /// /// A byte array that contains a hash value to place directly into the hash object. Before setting this value, the size of the hash /// value must be determined by using the CryptGetHashParam function to read the HP_HASHSIZE value. Some cryptographic service /// providers (CSPs) do not support this capability. /// /// /// /// Note Some CSP types can add additional values that can be set by using this function. /// /// /// A value data buffer. Place the value data in this buffer before calling CryptSetHashParam. The form of this data varies, /// depending on the value number. /// /// This parameter is reserved for future use and must be set to zero. /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_BUSY /// The CSP context is currently being used by another process. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero or the pbData buffer contains a value that is not valid. /// /// /// NTE_BAD_HASH /// The hash object specified by the hHash parameter is not valid. /// /// /// NTE_BAD_TYPE /// The dwParam parameter specifies an unknown value. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hKey key was created cannot be found. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// /// /// /// Occasionally, a hash value that has been generated elsewhere must be signed. This can be done by using the following sequence of operations: /// /// /// /// Create a hash object by using CryptCreateHash. /// /// /// Set the HP_HASHVAL value. /// /// /// Sign the hash value by using CryptSignHash and obtain a digital signature block. /// /// /// Destroy the hash object by using CryptDestroyHash. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsethashparam BOOL CryptSetHashParam( HCRYPTHASH // hHash, DWORD dwParam, const BYTE *pbData, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "0c8d3ef9-e7b5-4e49-a2f8-9c85b16549da")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptSetHashParam(HCRYPTHASH hHash, HashParam dwParam, [In] IntPtr pbData, uint dwFlags = 0); /// /// The CryptSetKeyParam function customizes various aspects of a session key's operations. The values set by this function are not /// persisted to memory and can only be used with in a single session. /// /// The Microsoft Base Cryptographic Provider does not permit setting values for key exchange or signature keys; however, custom /// providers can define values that can be set for its keys. /// /// /// A handle to the key for which values are to be set. /// /// The following tables contain predefined values that can be used. /// For all key types, this parameter can contain one of the following values. /// /// /// Value /// Meaning /// /// /// KP_ALGID /// /// pbData points to an appropriate ALG_ID. This is used when exchanging session keys with the Microsoft Base Digital Signature /// Standard (DSS), Diffie-Hellman Cryptographic Provider, or compatible CSPs. After a key is agreed upon with the CryptImportKey /// function, the session key is enabled for use by setting its algorithm type. /// /// /// /// KP_CERTIFICATE /// /// pbData is the address of a buffer that contains the X.509 certificate that has been encoded by using Distinguished Encoding /// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key. /// /// /// /// KP_PERMISSIONS /// pbData points to a DWORD value that specifies zero or more permission flags. For a description of these flags, see CryptGetKeyParam. /// /// /// KP_SALT /// /// pbData points to a BYTE array that specifies a new salt value to be made part of the session key. The size of the salt value /// varies depending on the CSP being used. Before setting this value, determine the size of the salt value by calling the /// CryptGetKeyParam function. Salt values are used to make the session keys more unique, which makes dictionary attacks more /// difficult. The salt value is zero by default for Microsoft Base Cryptographic Provider. /// /// /// /// KP_SALT_EX /// pbData points to a CRYPT_INTEGER_BLOB structure that contains the salt. For more information, see Specifying a Salt Value. /// /// /// /// If a Digital Signature Standard (DSS) key is specified by the hKey parameter, the dwParam value can also be set to one of the /// following values. /// /// /// /// Value /// Meaning /// /// /// KP_G /// /// pbData points to the generator G from the DSS key BLOB. The data is in the form of a CRYPT_INTEGER_BLOB structure, where the /// pbData member is the value, and the cbData member is the length of the value. The value is expected with no header information /// and in little-endian form. /// /// /// /// KP_P /// /// pbData points to the prime modulus P of a DSS key BLOB. The data is in the form of a CRYPT_INTEGER_BLOB structure. The pbData /// member is the value, and the cbData member is the length of the value. The value is expected with no header information and in /// little-endian form. /// /// /// /// KP_Q /// /// pbData points to the prime Q of a DSS key BLOB. The data is in the form of a CRYPT_INTEGER_BLOB structure where the pbData /// member is the value, and the cbData member is the length of the value. The value is expected with no header information and in /// little-endian form. /// /// /// /// KP_X /// /// After the P, Q, and G values have been set, a call that specifies the KP_X value for dwParam and NULL for the pbData parameter /// can be made to the CryptSetKeyParam function. This causes the X and Y values to be generated. /// /// /// /// /// If a Diffie-Hellman algorithm or Digital Signature Algorithm (DSA) key is specified by hKey, the dwParam value can also be set /// to one of the following values. /// /// /// /// Value /// Meaning /// /// /// KP_CMS_DH_KEY_INFO /// /// Sets the information for an imported Diffie-Hellman key. The pbData parameter is the address of a CMS_DH_KEY_INFO structure that /// contains the key information to be set. /// /// /// /// KP_PUB_PARAMS /// /// Sets the public parameters (P, Q, G, and so on) of a DSS or Diffie-Hellman key. The key handle for this key must be in the /// PREGEN state, generated with the CRYPT_PREGEN flag. The pbData parameter must be a pointer to a DATA_BLOB structure where the /// data in this structure is a DHPUBKEY_VER3 or DSSPUBKEY_VER3 BLOB. The function copies the public parameters from this /// CRYPT_INTEGER_BLOB structure to the key handle. After this call is made, the KP_X parameter value should be used with /// CryptSetKeyParam to create the actual private key. The KP_PUB_PARAMS parameter is used as one call rather than multiple calls /// with the parameter values KP_P, KP_Q, and KP_G. /// /// /// /// /// If a block cipher session key is specified by the hKey parameter, the dwParam value can also be set to one of the following values. /// /// /// /// Value /// Meaning /// /// /// KP_EFFECTIVE_KEYLEN /// /// This value type can only be used with RC2 keys and has been added because of the implementation of the CryptSetKeyParam function /// in the Microsoft Enhanced Cryptographic Provider prior to Windows 2000. In the previous implementation, the RC2 keys in the /// Enhanced Provider were 128 bits in strength, but the effective key length used to expand keys into the key table was only 40 /// bits. This reduced the strength of the algorithm to 40 bits. To maintain backward compatibility, the previous implementation /// will remain as is. However, the effective key length can be set to be greater than 40 bits by using KP_EFFECTIVE_KEYLEN in the /// CryptSetKeyParam call. The effective key length is passed in the pbData parameter as a pointer to a DWORD value with the /// effective key length value. The minimum effective key length on the Microsoft Base Cryptographic Provider is one, and the /// maximum is 40. In the Microsoft Enhanced Cryptographic Provider, the minimum is one and the maximum is 1,024. The key length /// must be set prior to encrypting or decrypting with the key. /// /// /// /// KP_HIGHEST_VERSION /// /// Sets the highest Transport Layer Security (TLS) version allowed. This property only applies to SSL and TLS keys. The pbData /// parameter is the address of a DWORD variable that contains the highest TLS version number supported. /// /// /// /// KP_IV /// /// pbData points to a BYTE array that specifies the initialization vector. This array must contain BlockLength/8 elements. For /// example, if the block length is 64 bits, the initialization vector consists of 8 bytes. The initialization vector is set to zero /// by default for the Microsoft Base Cryptographic Provider. /// /// /// /// KP_KEYVAL /// /// Set the key value for a Data Encryption Standard (DES) key. The pbData parameter is the address of a buffer that contains the /// key. This buffer must be the same length as the key. This property only applies to DES keys. /// /// /// /// KP_PADDING /// /// Set the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that identifies the /// padding method used by the cipher. This can be one of the following values. PKCS5_PADDING Specifies the PKCS 5 (sec 6.2) padding /// method. RANDOM_PADDING The padding uses a random number. This padding method is not supported by the Microsoft supplied CSPs. /// ZERO_PADDING The padding uses zeros. This padding method is not supported by the Microsoft supplied CSPs. /// /// /// /// KP_MODE /// /// pbData points to a DWORD value that specifies the cipher mode to be used. For a list of the defined cipher modes, see /// CryptGetKeyParam. The cipher mode is set to CRYPT_MODE_CBC by default for the Microsoft Base Cryptographic Provider. /// /// /// /// KP_MODE_BITS /// /// pbData points to a DWORD value that indicates the number of bits processed per cycle when the Output Feedback (OFB) or Cipher /// Feedback (CFB) cipher mode is used. The number of bits processed per cycle is set to 8 by default for the Microsoft Base /// Cryptographic Provider. /// /// /// /// If an RSA key is specified in the hKey parameter, the dwParam parameter value can be the following value. /// /// /// Value /// Meaning /// /// /// KP_OAEP_PARAMS /// /// Set the Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2) parameters for the key. The pbData parameter is the /// address of a CRYPT_DATA_BLOB structure that contains the OAEP label. This property only applies to RSA keys. /// /// /// /// Note that the following values are not used: /// /// /// KP_ADMIN_PIN /// /// /// KP_CMS_KEY_INFO /// /// /// KP_INFO /// /// /// KP_KEYEXCHANGE_PIN /// /// /// KP_PRECOMP_MD5 /// /// /// KP_PRECOMP_SHA /// /// /// KP_PREHASH /// /// /// KP_PUB_EX_LEN /// /// /// KP_PUB_EX_VAL /// /// /// KP_RA /// /// /// KP_RB /// /// /// KP_ROUNDS /// /// /// KP_RP /// /// /// KP_SIGNATURE_PIN /// /// /// KP_Y /// /// /// /// /// A pointer to a buffer initialized with the value to be set before calling CryptSetKeyParam. The form of this data varies /// depending on the value of dwParam. /// /// /// Used only when dwParam is KP_ALGID. The dwFlags parameter is used to pass in flag values for the enabled key. The dwFlags /// parameter can hold values such as the key size and the other flag values allowed when generating the same type of key with /// CryptGenKey. For information about allowable flag values, see CryptGenKey. /// /// /// If the function succeeds, the return value is nonzero (TRUE). /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_BUSY /// The CSP context is currently being used by another process. /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero, or the pbData buffer contains a value that is not valid. /// /// /// NTE_BAD_TYPE /// The dwParam parameter specifies an unknown parameter. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hKey key was created cannot be found. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// NTE_FIXEDPARAMETER /// /// Some CSPs have hard-coded P, Q, and G values. If this is the case, then using KP_P, KP_Q, and KP_G for the value of dwParam /// causes this error. /// /// /// /// /// /// /// If the KP_Q, KP_P, or KP_X parameters are set on a PREGEN Diffie-Hellman or DSS key, the key lengths must be compatible with the /// key length set using the upper 16 bits of the dwFlags parameter when the key was created using CryptGenKey. If no key length was /// set in CryptGenKey, the default key length was used. This will create an error if a nondefault key length is used to set /// P, Q, or X. /// /// Examples /// /// For an example that uses this function, see Example C Program: Duplicating a Session Key. For more code that uses this function, /// see Example C Program: Setting and Getting Session Key Parameters . /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetkeyparam BOOL CryptSetKeyParam( HCRYPTKEY hKey, // DWORD dwParam, const BYTE *pbData, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "e99a84a2-c23e-4251-8062-dd286ccc29b7")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptSetKeyParam(HCRYPTKEY hKey, KeyParam dwParam, [In] IntPtr pbData, uint dwFlags); /// /// The CryptSetProvider function specifies the current user's default cryptographic service provider (CSP). /// /// If a current user's default provider is set, that default provider is acquired by any call by that user to CryptAcquireContext /// specifying a dwProvType provider type but not a CSP name. /// /// An enhanced version of this function, CryptSetProviderEx, is also available. /// Note Typical applications do not use this function. It is intended for use solely by administrative applications. /// /// /// Name of the new default CSP. The named CSP must be installed on the computer. For a list of available cryptographic providers, /// see Cryptographic Provider Names. /// /// Provider type of the CSP specified by pszProvName. /// /// If the function succeeds, the return value is nonzero (TRUE). /// /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error /// codes are listed in the following table. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// The operating system ran out of memory during the operation. /// /// /// Errors can also be propagated from internal calls to RegCreateKeyEx and RegSetValueEx. /// /// /// /// Typical applications do not specify a CSP name when calling CryptAcquireContext; however, an application does have the option of /// selecting a specific CSP. This gives a user the freedom to select a CSP with an appropriate level of security. /// /// /// Since calling CryptSetProvider determines the CSP of a specified type used by all applications that run from that point /// on, this function must not be called without users' consent. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetprovidera BOOL CryptSetProviderA( LPCSTR // pszProvName, DWORD dwProvType ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "44023a0c-3fb4-4746-a676-1671c3ad901b")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptSetProvider([MarshalAs(UnmanagedType.LPTStr)] string pszProvName, uint dwProvType); /// /// /// The CryptSetProviderEx function specifies the default cryptographic service provider (CSP) of a specified provider type for the /// local computer or current user. /// /// Typical applications do not use this function. It is intended for use solely by administrative applications. /// /// /// The name of the new default CSP. This must be a CSP installed on the computer. For a list of available cryptographic providers, /// see Cryptographic Provider Names. /// /// The provider type of the CSP specified by pszProvName. /// This parameter is reserved for future use and must be NULL. /// /// The following flag values are defined. /// /// /// Value /// Meaning /// /// /// CRYPT_DELETE_DEFAULT 0x00000004 /// Can be used in conjunction with CRYPT_MACHINE_DEFAULT or CRYPT_USER_DEFAULT to delete the default. /// /// /// CRYPT_USER_DEFAULT 0x00000002 /// Causes the user-context default CSP of the specified type to be set. /// /// /// CRYPT_MACHINE_DEFAULT 0x00000001 /// Causes the computer default CSP of the specified type to be set. /// /// /// /// /// If the function succeeds, the return value is nonzero ( TRUE). /// /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. Possible /// error codes include those shown in the following table. /// /// /// /// Return code /// Description /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// The operating system ran out of memory. /// /// /// /// /// Most applications do not specify a CSP name when calling the CryptAcquireContext function; however, an application can specify a /// CSP name and thereby select a CSP with an appropriate level of security. Because calls to CryptSetProviderEx determine /// the CSP of a specified type used by all applications from that point on, CryptSetProviderEx must never be called without /// a user's consent. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetproviderexa BOOL CryptSetProviderExA( LPCSTR // pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "5f0c2724-5144-4a22-a7da-2a5162f06f5d")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptSetProviderEx([MarshalAs(UnmanagedType.LPTStr)] string pszProvName, uint dwProvType, [Optional] IntPtr pdwReserved, CryptProviderFlags dwFlags); /// /// The CryptSetProvParam function customizes the operations of a cryptographic service provider (CSP). This function is commonly /// used to set a security descriptor on the key container associated with a CSP to control access to the private keys in that key container. /// /// /// The handle of a CSP for which to set values. This handle must have already been created by using the CryptAcquireContext function. /// /// /// Specifies the parameter to set. This can be one of the following values. /// /// /// Value /// Meaning /// /// /// PP_CLIENT_HWND 1 (0x1) /// /// Set the window handle that the provider uses as the parent of any dialog boxes it creates. pbData contains a pointer to an HWND /// that contains the parent window handle. This parameter must be set before calling CryptAcquireContext because many CSPs will /// display a user interface when CryptAcquireContext is called. You can pass NULL for the hProv parameter to set this window handle /// for all cryptographic contexts subsequently acquired within this process. /// /// /// /// PP_DELETEKEY 24 (0x18) /// /// Delete the ephemeral key associated with a hash, encryption, or verification context. This will free memory and clear registry /// settings associated with the key. /// /// /// /// PP_KEYEXCHANGE_ALG /// This constant is not used. /// /// /// PP_KEYEXCHANGE_PIN 32 (0x20) /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. /// /// /// PP_KEYEXCHANGE_KEYSIZE /// This constant is not used. /// /// /// PP_KEYSET_SEC_DESCR 8 (0x8) /// /// Sets the security descriptor on the key storage container. The pbData parameter is the address of a SECURITY_DESCRIPTOR /// structure that contains the new security descriptor for the key storage container. /// /// /// /// PP_PIN_PROMPT_STRING 44 (0x2C) /// /// Sets an alternate prompt string to display to the user when the user's PIN is requested. The pbData parameter is a pointer to a /// null-terminated Unicode string. /// /// /// /// PP_ROOT_CERTSTORE 46 (0x2E) /// /// Sets the root certificate store for the smart card. The provider will copy the root certificates from this store onto the smart /// card. The pbData parameter is an HCERTSTORE variable that contains the handle of the new certificate store. The provider will /// copy the certificates from the store during this call, so it is safe to close this store after this function is called. Windows /// XP and Windows Server 2003: This parameter is not supported. /// /// /// /// PP_SIGNATURE_ALG /// This constant is not used. /// /// /// PP_SIGNATURE_PIN 33 (0x21) /// Specifies the signature PIN. The pbData parameter is a null-terminated ASCII string that represents the PIN. /// /// /// PP_SIGNATURE_KEYSIZE /// This constant is not used. /// /// /// PP_UI_PROMPT 21 (0x15) /// /// For a smart card provider, sets the search string that is displayed to the user as a prompt to insert the smart card. This /// string is passed as the lpstrSearchDesc member of the OPENCARDNAME_EX structure that is passed to the SCardUIDlgSelectCard /// function. This string is used for the lifetime of the calling process. The pbData parameter is a pointer to a null-terminated /// Unicode string. /// /// /// /// PP_USE_HARDWARE_RNG 38 (0x26) /// /// Specifies that the CSP must exclusively use the hardware random number generator (RNG). When PP_USE_HARDWARE_RNG is set, random /// values are taken exclusively from the hardware RNG and no other sources are used. If a hardware RNG is supported by the CSP and /// it can be exclusively used, the function succeeds and returns TRUE; otherwise, the function fails and returns FALSE. The pbData /// parameter must be NULL and dwFlags must be zero when using this value. None of the Microsoft CSPs currently support using a /// hardware RNG. /// /// /// /// PP_USER_CERTSTORE 42 (0x2A) /// /// Specifies the user certificate store for the smart card. This certificate store contains all of the user certificates that are /// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING encoding /// and should contain the CERT_KEY_PROV_INFO_PROP_ID property. The pbData parameter is an HCERTSTORE variable that receives the /// handle of an in-memory certificate store. When this handle is no longer needed, the caller must close it by using the /// CertCloseStore function. Windows Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// PP_SECURE_KEYEXCHANGE_PIN 47 (0x2F) /// Specifies that an encrypted key exchange PIN is contained in pbData. The pbData parameter contains a DATA_BLOB. /// /// /// PP_SECURE_SIGNATURE_PIN 48 (0x30) /// Specifies that an encrypted signature PIN is contained in pbData. The pbData parameter contains a DATA_BLOB. /// /// /// PP_SMARTCARD_READER 43 (0x2B) /// /// Specifies the name of the smart card reader. The pbData parameter is the address of an ANSI character array that contains a /// null-terminated ANSI string that contains the name of the smart card reader. Windows Server 2003 and Windows XP: This parameter /// is not supported. /// /// /// /// PP_SMARTCARD_GUID 45 (0x2D) /// /// Specifies the identifier of the smart card. The pbData parameter is the address of a GUID structure that contains the identifier /// of the smart card. Windows Server 2003 and Windows XP: This parameter is not supported. /// /// /// /// /// /// A pointer to a data buffer that contains the value to be set as a provider parameter. The form of this data varies depending on /// the dwParam value. If dwParam contains PP_USE_HARDWARE_RNG, this parameter must be NULL. /// /// /// /// If dwParam contains PP_KEYSET_SEC_DESCR, dwFlags contains the SECURITY_INFORMATION applicable bit flags, as /// defined in the Platform SDK. Key-container security is handled by using SetFileSecurity and GetFileSecurity. /// /// These bit flags can be combined by using a bitwise- OR operation. For more information, see CryptGetProvParam. /// If dwParam is PP_USE_HARDWARE_RNG or PP_DELETEKEY, dwFlags must be set to zero. /// /// /// If the function succeeds, the return value is nonzero ( TRUE). /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Error codes include the following. /// /// /// Return code /// Description /// /// /// ERROR_BUSY /// The CSP context is currently being used by another process. /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero or the pbData buffer contains a value that is not valid. /// /// /// NTE_BAD_TYPE /// The dwParam parameter specifies an unknown parameter. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hKey key was created cannot be found. /// /// /// NTE_FAIL /// The function failed in some unexpected way. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetprovparam BOOL CryptSetProvParam( HCRYPTPROV // hProv, DWORD dwParam, const BYTE *pbData, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "98306a7b-b218-4eb4-99f0-0b5bcc632a13")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptSetProvParam(HCRYPTPROV hProv, ProvParam dwParam, [In] IntPtr pbData, uint dwFlags); /// /// The CryptSignHash function signs data. Because all signature algorithms are asymmetric and thus slow, CryptoAPI does not allow /// data to be signed directly. Instead, data is first hashed, and CryptSignHash is used to sign the hash. /// /// Handle of the hash object to be signed. /// /// Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE. /// The signature algorithm used is specified when the key pair is originally created. /// The only signature algorithm that the Microsoft Base Cryptographic Provider supports is the RSA Public Key algorithm. /// /// /// This parameter is no longer used and must be set to NULL to prevent security vulnerabilities. However, it is still /// supported for backward compatibility in the Microsoft Base Cryptographic Provider. /// /// /// The following flag values are defined. /// /// /// Value /// Meaning /// /// /// CRYPT_NOHASHOID 0x00000001 /// /// Used with RSA providers. The hash object identifier (OID) is not placed in the RSA public key encryption. If this flag is not /// set, the hash OID in the default signature is as specified in the definition of DigestInfo in PKCS #1. /// /// /// /// CRYPT_TYPE2_FORMAT 0x00000002 /// This flag is not used. /// /// /// CRYPT_X931_FORMAT 0x00000004 /// Use the RSA signature padding method specified in the ANSI X9.31 standard. /// /// /// /// /// A pointer to a buffer receiving the signature data. /// /// This parameter can be NULL to set the buffer size for memory allocation purposes. For more information, see Retrieving /// Data of Unknown Length. /// /// /// /// /// A pointer to a DWORD value that specifies the size, in bytes, of the pbSignature buffer. When the function returns, the /// DWORD value contains the number of bytes stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually /// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to /// by this parameter is updated to reflect the actual size of the data copied to the buffer. /// /// /// /// If the function succeeds, the function returns TRUE. /// If the function fails, it returns FALSE. For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// ERROR_MORE_DATA /// /// The buffer specified by the pbSignature parameter is not large enough to hold the returned data. The required buffer size, in /// bytes, is in the pdwSigLenDWORD value. /// /// /// /// NTE_BAD_ALGID /// The hHash handle specifies an algorithm that this CSP does not support, or the dwKeySpec parameter has an incorrect value. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hash object specified by the hHash parameter is not valid. /// /// /// NTE_BAD_UID /// The CSP context that was specified when the hash object was created cannot be found. /// /// /// NTE_NO_KEY /// The private key specified by dwKeySpec does not exist. /// /// /// NTE_NO_MEMORY /// The CSP ran out of memory during the operation. /// /// /// /// /// /// Before calling this function, the CryptCreateHash function must be called to get a handle to a hash object. The CryptHashData or /// CryptHashSessionKey function is then used to add the data or session keys to the hash object. The CryptSignHash function /// completes the hash. /// /// /// While the DSS CSP supports hashing with both the MD5 and the SHA hash algorithms, the DSS CSP only supports signing SHA hashes. /// /// /// After this function is called, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail. /// /// After the application finishes using the hash, destroy the hash object by calling the CryptDestroyHash function. /// /// By default, the Microsoft RSA providers use the PKCS #1 padding method for the signature. The hash OID in the DigestInfo /// element of the signature is automatically set to the algorithm OID associated with the hash object. Using the /// CRYPT_NOHASHOID flag will cause this OID to be omitted from the signature. /// /// /// Occasionally, a hash value that has been generated elsewhere must be signed. This can be done by using the following sequence of operations: /// /// /// /// Create a hash object by using CryptCreateHash. /// /// /// Set the hash value in the hash object by using the HP_HASHVAL value of the dwParam parameter in CryptSetHashParam. /// /// /// Sign the hash value by using CryptSignHash and obtain a digital signature block. /// /// /// Destroy the hash object by using CryptDestroyHash. /// /// /// Examples /// /// The following example shows signing data by first hashing the data to be signed and then signing the hash by using the /// CryptSignHash function. /// /// /// For a complete example including the context for this code, see Example C Program: Signing a Hash and Verifying the Hash Signature. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsignhasha BOOL CryptSignHashA( HCRYPTHASH hHash, // DWORD dwKeySpec, LPCSTR szDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "9cf0de04-fdad-457d-8137-16d98f915cd5")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptSignHash(HCRYPTHASH hHash, CertKeySpec dwKeySpec, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szDescription, CryptSignFlags dwFlags, [Out, Optional] IntPtr pbSignature, ref uint pdwSigLen); /// /// The CryptVerifySignature function verifies the signature of a hash object. /// /// Before calling this function, CryptCreateHash must be called to create the handle of a hash object. CryptHashData or /// CryptHashSessionKey is then used to add data or session keys to the hash object. /// /// After CryptVerifySignature completes, only CryptDestroyHash can be called by using the hHash handle. /// /// A handle to the hash object to verify. /// The address of the signature data to be verified. /// The number of bytes in the pbSignature signature data. /// /// A handle to the public key to use to authenticate the signature. This public key must belong to the key pair that was originally /// used to create the digital signature. /// /// /// This parameter should no longer be used and must be set to NULL to prevent security vulnerabilities. However, it is still /// supported for backward compatibility in the Microsoft Base Cryptographic Provider. /// /// /// The following flag values are defined. /// /// /// Value /// Meaning /// /// /// CRYPT_NOHASHOID 0x00000001 /// /// This flag is used with RSA providers. When verifying the signature, the hash object identifier (OID) is not expected to be /// present or checked. If this flag is not set, the hash OID in the default signature is verified as specified in the definition of /// DigestInfo in PKCS #7. /// /// /// /// CRYPT_TYPE2_FORMAT 0x00000002 /// This flag is not used. /// /// /// CRYPT_X931_FORMAT 0x00000004 /// Use X.931 support for the FIPS 186-2–compliant version of RSA (rDSA). /// /// /// /// /// If the function succeeds, the return value is TRUE. /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// ERROR_INVALID_HANDLE /// One of the parameters specifies a handle that is not valid. /// /// /// ERROR_INVALID_PARAMETER /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. /// /// /// NTE_BAD_FLAGS /// The dwFlags parameter is nonzero. /// /// /// NTE_BAD_HASH /// The hash object specified by the hHash parameter is not valid. /// /// /// NTE_BAD_KEY /// The hPubKey parameter does not contain a handle to a valid public key. /// /// /// NTE_BAD_SIGNATURE /// /// The signature was not valid. This might be because the data itself has changed, the description string did not match, or the /// wrong public key was specified by hPubKey. This error can also be returned if the hashing or signature algorithms do not match /// the ones used to create the signature. /// /// /// /// NTE_BAD_UID /// The cryptographic service provider (CSP) context that was specified when the hash object was created cannot be found. /// /// /// NTE_NO_MEMORY /// The CSP ran out of memory during the operation. /// /// /// /// /// /// The CryptVerifySignature function completes the hash. After this call, no more data can be added to the hash. Additional /// calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be /// called to destroy the hash object. /// /// /// If you generate a signature by using the .NET Framework APIs and try to verify it by using the CryptVerifySignature /// function, the function will fail and GetLastError will return NTE_BAD_SIGNATURE. This is due to the different byte orders /// between the native Win32 API and the .NET Framework API. /// /// /// The native cryptography API uses little-endian byte order while the .NET Framework API uses big-endian byte order. If you are /// verifying a signature generated by using a .NET Framework API, you must swap the order of signature bytes before calling the /// CryptVerifySignature function to verify the signature. /// /// Examples /// /// For an example that uses the CryptVerifySignature function, see Example C Program: Signing a Hash and Verifying the Hash Signature. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifysignaturea BOOL CryptVerifySignatureA( // HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCSTR szDescription, DWORD dwFlags ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("wincrypt.h", MSDNShortId = "3119eabc-90ff-42c6-b3fa-e8be625f6d1e")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptVerifySignature(HCRYPTHASH hHash, [In] IntPtr pbSignature, uint dwSigLen, HCRYPTKEY hPubKey, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szDescription, CryptSignFlags dwFlags); private static TRet CryptGetValue(CryptGetValueMethod func, THandle hKey, TEnum dwParam, uint dwFlags = 0) where THandle : struct where TEnum : Enum { var len = 0U; if (!func(hKey, dwParam, default, ref len, dwFlags)) Win32Error.ThrowLastError(); using var mem = new SafeHGlobalHandle(len); if (!func(hKey, dwParam, mem, ref len, dwFlags)) Win32Error.ThrowLastError(); return mem.DangerousGetHandle().Convert(mem.Size); } /// /// The HMAC_INFO structure specifies the hash algorithm and the inner and outer strings that are to be used to calculate the /// HMAC hash. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-hmac_info typedef struct _HMAC_Info { ALG_ID HashAlgid; // BYTE *pbInnerString; DWORD cbInnerString; BYTE *pbOuterString; DWORD cbOuterString; } HMAC_INFO, *PHMAC_INFO; [PInvokeData("wincrypt.h", MSDNShortId = "0c9a9b60-077d-48c0-a5a6-01640cfc0c4e")] [StructLayout(LayoutKind.Sequential)] public struct HMAC_INFO { /// Specifies the hash algorithm to be used. public ALG_ID HashAlgid; /// /// A pointer to the inner string to be used in the HMAC calculation. The default inner string is defined as the byte 0x36 /// repeated 64 times. /// public IntPtr pbInnerString; /// /// The count of bytes in pbInnerString. The CSP uses the default inner string if cbInnerString is equal to zero. /// public uint cbInnerString; /// /// A pointer to the outer string to be used in the HMAC calculation. The default outer string is defined as the byte 0x5C /// repeated 64 times. /// public IntPtr pbOuterString; /// /// The count of bytes in pbOuterString. The CSP uses the default outer string if cbOuterString is equal to zero. /// public uint cbOuterString; } /// /// The PROV_ENUMALGS structure is used with the CryptGetProvParam function when the PP_ENUMALGS parameter is retrieved to /// contain information about an algorithm supported by a cryptographic service provider (CSP). /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-prov_enumalgs // typedef struct _PROV_ENUMALGS { ALG_ID aiAlgid; DWORD dwBitLen; DWORD dwNameLen; CHAR szName[20]; } PROV_ENUMALGS; [PInvokeData("wincrypt.h", MSDNShortId = "8301d07f-88aa-49b4-9091-8f515b585c57")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct PROV_ENUMALGS { /// One of the ALG_ID values that identifies the algorithm. public ALG_ID aiAlgid; /// The default key length, in bits, of the algorithm. public uint dwBitLen; /// The length, in CHARs, of the szName string. This length includes the terminating null character. public uint dwNameLen; /// A null-terminated ANSI string that contains the name of the algorithm. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string szName; } /// /// The PROV_ENUMALGS_EX structure is used with the CryptGetProvParam function when the PP_ENUMALGS_EX parameter is /// retrieved to contain information about an algorithm supported by a cryptographic service provider (CSP). /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-prov_enumalgs_ex typedef struct _PROV_ENUMALGS_EX { // ALG_ID aiAlgid; DWORD dwDefaultLen; DWORD dwMinLen; DWORD dwMaxLen; DWORD dwProtocols; DWORD dwNameLen; CHAR szName[20]; DWORD // dwLongNameLen; CHAR szLongName[40]; } PROV_ENUMALGS_EX; [PInvokeData("wincrypt.h", MSDNShortId = "239dbc6f-c3fa-4f97-aa9a-4993fe726a98")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct PROV_ENUMALGS_EX { /// One of the ALG_ID values that identifies the algorithm. public ALG_ID aiAlgid; /// The default key length, in bits, of the algorithm. public uint dwDefaultLen; /// The minimum key length, in bits, of the algorithm. public uint dwMinLen; /// The maximum key length, in bits, of the algorithm. public uint dwMaxLen; /// /// Zero or a combination of one or more of the Protocol Flags values that identifies the protocols supported by the algorithm. /// public uint dwProtocols; /// The length, in CHAR s, of the szName string. This length includes the terminating null character. public uint dwNameLen; /// A null-terminated ANSI string that contains the name of the algorithm. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string szName; /// The length, in CHAR s, of the szLongName string. This length includes the terminating null character. public uint dwLongNameLen; /// A null-terminated ANSI string that contains the long name of the algorithm. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] public string szLongName; } /// Provides a for that is disposed using . public class SafeHCRYPTHASH : SafeHANDLE { /// Represents a NULL handle for . This must be used instead of . public static readonly SafeHCRYPTHASH Null = new SafeHCRYPTHASH(IntPtr.Zero, false); /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeHCRYPTHASH(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeHCRYPTHASH() : base() { } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator HCRYPTHASH(SafeHCRYPTHASH h) => h.handle; /// protected override bool InternalReleaseHandle() => CryptDestroyHash(handle); } /// Provides a for that is disposed using . public class SafeHCRYPTPROV : SafeHANDLE { /// Represents a NULL handle for . This must be used instead of . public static readonly SafeHCRYPTPROV Null = new SafeHCRYPTPROV(IntPtr.Zero, false); /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeHCRYPTPROV(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeHCRYPTPROV() : base() { } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator HCRYPTPROV(SafeHCRYPTPROV h) => h.handle; /// protected override bool InternalReleaseHandle() => CryptReleaseContext(handle); } /// /// The following cryptographic service provider (CSP) names are defined in Wincrypt.h. These constants are used with the /// CryptAcquireContext and CryptSetProvider functions. /// // https://docs.microsoft.com/en-us/windows/win32/seccrypto/cryptographic-provider-names [PInvokeData("wincrypt.h", MSDNShortId = "97e9a708-83b5-48b3-9d16-f7b54367dc4e")] public static class CryptProviderName { /// The Microsoft DSS and Diffie-Hellman/Schannel Cryptographic Provider. public const string MS_DEF_DH_SCHANNEL_PROV = "Microsoft DH Schannel Cryptographic Provider"; /// The Microsoft Base DSS and Diffie-Hellman Cryptographic Provider. public const string MS_DEF_DSS_DH_PROV = "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider"; /// The Microsoft DSS Cryptographic Provider. public const string MS_DEF_DSS_PROV = "Microsoft Base DSS Cryptographic Provider"; /// The Microsoft Base Cryptographic Provider. public const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0"; /// The Microsoft RSA/Schannel Cryptographic Provider. public const string MS_DEF_RSA_SCHANNEL_PROV = "Microsoft RSA Schannel Cryptographic Provider"; /// The Microsoft RSA Signature Cryptographic Provider is not supported. public const string MS_DEF_RSA_SIG_PROV = "Microsoft RSA Signature Cryptographic Provider"; /// The Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider. public const string MS_ENH_DSS_DH_PROV = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider"; /// /// The Microsoft AES Cryptographic Provider. /// **Windows XP: **"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)" /// public const string MS_ENH_RSA_AES_PROV = "Microsoft Enhanced RSA and AES Cryptographic Provider"; /// The Microsoft Enhanced Cryptographic Provider. public const string MS_ENHANCED_PROV = "Microsoft Enhanced Cryptographic Provider v1.0"; /// The Microsoft Base Smart Card Cryptographic Service Provider. public const string MS_SCARD_PROV = "Microsoft Base Smart Card Crypto Provider"; /// The Microsoft Strong Cryptographic Provider. public const string MS_STRONG_PROV = "Microsoft Strong Cryptographic Provider"; } } }