internal static SafeCspHandle AcquireCsp(string keyContainer, string providerName, ProviderType providerType, CryptAcquireContextFlags flags, bool throwPlatformException) { Contract.Ensures(Contract.Result <SafeCspHandle>() != null && !Contract.Result <SafeCspHandle>().IsInvalid&& !Contract.Result <SafeCspHandle>().IsClosed); SafeCspHandle cspHandle = null; if (!UnsafeNativeMethods.CryptAcquireContext(out cspHandle, keyContainer, providerName, providerType, flags)) { // If the platform doesn't have the specified CSP, we'll either get a ProviderTypeNotDefined // or a KeysetNotDefined error depending on the CAPI version. int error = Marshal.GetLastWin32Error(); if (throwPlatformException && (error == (int)CapiNative.ErrorCode.ProviderTypeNotDefined || error == (int)CapiNative.ErrorCode.KeysetNotDefined)) { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } else { throw new CryptographicException(error); } } return(cspHandle); }
internal static void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer) { if (!CapiNative.UnsafeNativeMethods.CryptGenRandom(cspHandle, buffer.Length, buffer)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } }
internal static unsafe SafeCapiKeyHandle ImportSymmetricKey(SafeCspHandle provider, AlgorithmId algorithm, byte[] key) { int num = (Marshal.SizeOf(typeof(BLOBHEADER)) + Marshal.SizeOf(typeof(int))) + key.Length; byte[] dst = new byte[num]; fixed(byte *numRef = dst) { BLOBHEADER *blobheaderPtr = (BLOBHEADER *)numRef; blobheaderPtr->bType = KeyBlobType.PlainText; blobheaderPtr->bVersion = 2; blobheaderPtr->reserved = 0; blobheaderPtr->aiKeyAlg = algorithm; int *numPtr = (int *)(numRef + Marshal.SizeOf(blobheaderPtr[0])); numPtr[0] = key.Length; } Buffer.BlockCopy(key, 0, dst, Marshal.SizeOf(typeof(BLOBHEADER)) + Marshal.SizeOf(typeof(int)), key.Length); SafeCapiKeyHandle phKey = null; if (!UnsafeNativeMethods.CryptImportKey(provider, dst, dst.Length, SafeCapiKeyHandle.InvalidHandle, KeyFlags.Exportable, out phKey)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return(phKey); }
[System.Security.SecuritySafeCritical] // auto-generated #endif public RNGCryptoServiceProvider() { m_cspHandle = CapiNative.AcquireCsp(null, CapiNative.ProviderNames.MicrosoftEnhanced, CapiNative.ProviderType.RsaFull, CapiNative.CryptAcquireContextFlags.VerifyContext); }
internal static bool VerifySignature(SafeCspHandle cspHandle, SafeCspKeyHandle keyHandle, CapiNative.AlgorithmID signatureAlgorithm, CapiNative.AlgorithmID hashAlgorithm, byte[] hashValue, byte[] signature) { byte[] numArray = new byte[signature.Length]; Array.Copy((Array)signature, (Array)numArray, numArray.Length); Array.Reverse((Array)numArray); using (SafeCspHashHandle hashAlgorithm1 = CapiNative.CreateHashAlgorithm(cspHandle, hashAlgorithm)) { if (hashValue.Length != CapiNative.GetHashPropertyInt32(hashAlgorithm1, CapiNative.HashProperty.HashSize)) { throw new CryptographicException(-2146893822); } CapiNative.SetHashProperty(hashAlgorithm1, CapiNative.HashProperty.HashValue, hashValue); SafeCspHashHandle hHash = hashAlgorithm1; byte[] pbSignature = numArray; int length = pbSignature.Length; SafeCspKeyHandle hPubKey = keyHandle; // ISSUE: variable of the null type __Null local = null; int dwFlags = 0; if (CapiNative.UnsafeNativeMethods.CryptVerifySignature(hHash, pbSignature, length, hPubKey, (string)local, dwFlags)) { return(true); } int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != -2146893818) { throw new CryptographicException(lastWin32Error); } return(false); } }
internal static SafeCspHandle AcquireCsp(string keyContainer, string providerName, ProviderType providerType, CryptAcquireContextFlags flags) { Contract.Assert(keyContainer == null, "Key containers are not supported"); // Specifying both verify context (for an ephemeral key) and machine keyset (for a persisted machine key) // does not make sense. Additionally, Widows is beginning to lock down against uses of MACHINE_KEYSET // (for instance in the app container), even if verify context is present. Therefore, if we're using // an ephemeral key, strip out MACHINE_KEYSET from the flags. if (((flags & CryptAcquireContextFlags.VerifyContext) == CryptAcquireContextFlags.VerifyContext) && ((flags & CryptAcquireContextFlags.MachineKeyset) == CryptAcquireContextFlags.MachineKeyset)) { flags &= ~CryptAcquireContextFlags.MachineKeyset; } SafeCspHandle cspHandle = null; if (!UnsafeNativeMethods.CryptAcquireContext(out cspHandle, keyContainer, providerName, providerType, flags)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return(cspHandle); }
internal static bool VerifySignature(SafeCspHandle cspHandle, SafeCspKeyHandle keyHandle, CapiNative.AlgorithmID signatureAlgorithm, CapiNative.AlgorithmID hashAlgorithm, byte[] hashValue, byte[] signature) { byte[] array = new byte[signature.Length]; Array.Copy(signature, array, array.Length); Array.Reverse(array); bool result; using (SafeCspHashHandle safeCspHashHandle = CapiNative.CreateHashAlgorithm(cspHandle, hashAlgorithm)) { if (hashValue.Length != CapiNative.GetHashPropertyInt32(safeCspHashHandle, CapiNative.HashProperty.HashSize)) { throw new CryptographicException(-2146893822); } CapiNative.SetHashProperty(safeCspHashHandle, CapiNative.HashProperty.HashValue, hashValue); if (CapiNative.UnsafeNativeMethods.CryptVerifySignature(safeCspHashHandle, array, array.Length, keyHandle, null, 0)) { result = true; } else { int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != -2146893818) { throw new CryptographicException(lastWin32Error); } result = false; } } return(result); }
public CapiSymmetricAlgorithm(int blockSize, int feedbackSize, SafeCspHandle provider, SafeCapiKeyHandle key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, EncryptionMode encryptionMode) { this.m_blockSize = blockSize; this.m_encryptionMode = encryptionMode; this.m_paddingMode = paddingMode; this.m_provider = provider.Duplicate(); this.m_key = SetupKey(key, ProcessIV(iv, blockSize, cipherMode), cipherMode, feedbackSize); }
internal static T GetProviderParameterStruct <T>(SafeCspHandle provider, ProviderParameter parameter, ProviderParameterFlags flags) where T : struct { Contract.Requires(provider != null); Contract.Requires(parameter == ProviderParameter.EnumerateAlgorithms); // Figure out how big the parameter is int bufferSize = 0; IntPtr buffer = IntPtr.Zero; if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, buffer, ref bufferSize, flags)) { int errorCode = Marshal.GetLastWin32Error(); // NoMoreItems means that we've finished the enumeration we're currently working on, this is // not a real error, so return an empty structure to mark the end. if (errorCode == (int)ErrorCode.NoMoreItems) { return(new T()); } else if (errorCode != (int)ErrorCode.MoreData) { throw new CryptographicException(errorCode); } } Debug.Assert(Marshal.SizeOf(typeof(T)) <= bufferSize, "Buffer size does not match structure size"); // // Pull the parameter back and marshal it into the return structure // RuntimeHelpers.PrepareConstrainedRegions(); try { // Allocate in a CER because we could fail between the alloc and the assignment RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { buffer = Marshal.AllocCoTaskMem(bufferSize); } if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, buffer, ref bufferSize, flags)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return((T)Marshal.PtrToStructure(buffer, typeof(T))); } finally { if (buffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(buffer); } } }
internal static unsafe void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer, int offset, int count) { fixed(byte *pbBuffer = &buffer[offset]) { if (!CapiNative.UnsafeNativeMethods.CryptGenRandom(cspHandle, count, pbBuffer)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } }
internal static SafeCspHashHandle CreateHashAlgorithm(SafeCspHandle cspHandle, CapiNative.AlgorithmID algorithm) { SafeCspHashHandle phHash = (SafeCspHashHandle)null; if (!CapiNative.UnsafeNativeMethods.CryptCreateHash(cspHandle, algorithm, IntPtr.Zero, 0, out phHash)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return(phHash); }
internal static void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer) { Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); Contract.Assert(buffer != null && buffer.Length > 0, "buffer != null && buffer.Length > 0"); if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, buffer.Length, buffer)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } }
internal static bool VerifySignature(SafeCspHandle cspHandle, SafeCspKeyHandle keyHandle, AlgorithmID signatureAlgorithm, AlgorithmID hashAlgorithm, byte[] hashValue, byte[] signature) { Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); Contract.Assert(keyHandle != null && !keyHandle.IsInvalid, "keyHandle != null && !keyHandle.IsInvalid"); Contract.Assert(((AlgorithmClass)signatureAlgorithm & AlgorithmClass.Signature) == AlgorithmClass.Signature, "Invalid signature algorithm"); Contract.Assert(((AlgorithmClass)hashAlgorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm"); Contract.Assert(hashValue != null, "hashValue != null"); Contract.Assert(signature != null, "signature != null"); // CAPI and the CLR have inverse byte orders for signatures, so we need to reverse before verifying byte[] signatureValue = new byte[signature.Length]; Array.Copy(signature, signatureValue, signatureValue.Length); Array.Reverse(signatureValue); using (SafeCspHashHandle hashHandle = CreateHashAlgorithm(cspHandle, hashAlgorithm)) { // Make sure the hash value is the correct size and import it into the CSP if (hashValue.Length != GetHashPropertyInt32(hashHandle, HashProperty.HashSize)) { throw new CryptographicException((int)ErrorCode.BadHash); } SetHashProperty(hashHandle, HashProperty.HashValue, hashValue); // Do the signature verification. A TRUE result means that the signature was valid. A FALSE // result either means an invalid signature or some other error, so we need to check the last // error to see which occured. if (UnsafeNativeMethods.CryptVerifySignature(hashHandle, signatureValue, signatureValue.Length, keyHandle, null, 0)) { return(true); } else { int error = Marshal.GetLastWin32Error(); if (error != (int)ErrorCode.BadSignature) { throw new CryptographicException(error); } return(false); } } }
internal static SafeCspHandle AcquireCsp(string keyContainer, string providerName, CapiNative.ProviderType providerType, CapiNative.CryptAcquireContextFlags flags) { if ((flags & CapiNative.CryptAcquireContextFlags.VerifyContext) == CapiNative.CryptAcquireContextFlags.VerifyContext && (flags & CapiNative.CryptAcquireContextFlags.MachineKeyset) == CapiNative.CryptAcquireContextFlags.MachineKeyset) { flags &= ~CapiNative.CryptAcquireContextFlags.MachineKeyset; } SafeCspHandle phProv = (SafeCspHandle)null; if (!CapiNative.UnsafeNativeMethods.CryptAcquireContext(out phProv, keyContainer, providerName, providerType, flags)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return(phProv); }
internal static SafeCspHashHandle CreateHashAlgorithm(SafeCspHandle cspHandle, AlgorithmID algorithm) { Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); Contract.Assert(((AlgorithmClass)algorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm"); SafeCspHashHandle hashHandle = null; if (!UnsafeNativeMethods.CryptCreateHash(cspHandle, algorithm, IntPtr.Zero, 0, out hashHandle)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return(hashHandle); }
internal static unsafe void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer, int offset, int count) { Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); Contract.Assert(buffer != null && buffer.Length > 0, "buffer != null && buffer.Length > 0"); Contract.Assert(offset >= 0 && count > 0, "offset >= 0 && count > 0"); Contract.Assert(buffer.Length >= offset + count, "buffer.Length >= offset + count"); fixed(byte *pBuffer = &buffer[offset]) { if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, count, pBuffer)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } }
internal static SafeCspHandle AcquireCsp(string keyContainer, string providerName, ProviderType providerType, CryptAcquireContextFlags flags, bool throwPlatformException) { SafeCspHandle phProv = null; if (UnsafeNativeMethods.CryptAcquireContext(out phProv, keyContainer, providerName, providerType, flags)) { return(phProv); } int hr = Marshal.GetLastWin32Error(); if (!throwPlatformException || ((hr != -2146893801) && (hr != -2146893799))) { throw new CryptographicException(hr); } throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported")); }
// SafeCritical - we're not exposing out anything that we want to prevent untrusted code from getting at public CapiHashAlgorithm(string provider, CapiNative.ProviderType providerType, CapiNative.AlgorithmId algorithm) { Contract.Requires(!String.IsNullOrEmpty(provider)); Contract.Requires((CapiNative.AlgorithmClass)((uint)algorithm & (uint)CapiNative.AlgorithmClass.Hash) == CapiNative.AlgorithmClass.Hash); Contract.Ensures(m_cspHandle != null && !m_cspHandle.IsInvalid && !m_cspHandle.IsClosed); Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed); m_algorithmId = algorithm; m_cspHandle = CapiNative.AcquireCsp(null, provider, providerType, CapiNative.CryptAcquireContextFlags.VerifyContext, true); Initialize(); }
public AesCryptoServiceProvider() { string providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider"; if ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor == 1)) { providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"; } this.m_cspHandle = CapiNative.AcquireCsp(null, providerName, CapiNative.ProviderType.RsaAes, CapiNative.CryptAcquireContextFlags.None | CapiNative.CryptAcquireContextFlags.VerifyContext, true); base.FeedbackSizeValue = 8; int defaultKeySize = 0; if (FindSupportedKeySizes(this.m_cspHandle, out defaultKeySize).Length == 0) { throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported")); } base.KeySizeValue = defaultKeySize; }
internal static T GetProviderParameterStruct <T>(SafeCspHandle provider, ProviderParameter parameter, ProviderParameterFlags flags) where T : struct { T local; int pdwDataLen = 0; IntPtr zero = IntPtr.Zero; if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, zero, ref pdwDataLen, flags)) { int hr = Marshal.GetLastWin32Error(); if (hr == 0x103) { return(default(T)); } if (hr != 0xea) { throw new CryptographicException(hr); } } RuntimeHelpers.PrepareConstrainedRegions(); try { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { zero = Marshal.AllocCoTaskMem(pdwDataLen); } if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, zero, ref pdwDataLen, flags)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } local = (T)Marshal.PtrToStructure(zero, typeof(T)); } finally { if (zero != IntPtr.Zero) { Marshal.FreeCoTaskMem(zero); } } return(local); }
private static KeySizes[] FindSupportedKeySizes(SafeCspHandle csp, out int defaultKeySize) { if (s_supportedKeySizes == null) { List <KeySizes> list = new List <KeySizes>(); int num = 0; for (CapiNative.PROV_ENUMALGS prov_enumalgs = CapiNative.GetProviderParameterStruct <CapiNative.PROV_ENUMALGS>(csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.RestartEnumeration); prov_enumalgs.aiAlgId != CapiNative.AlgorithmId.None; prov_enumalgs = CapiNative.GetProviderParameterStruct <CapiNative.PROV_ENUMALGS>(csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.None)) { switch (prov_enumalgs.aiAlgId) { case CapiNative.AlgorithmId.Aes128: list.Add(new KeySizes(0x80, 0x80, 0)); if (0x80 > num) { num = 0x80; } break; case CapiNative.AlgorithmId.Aes192: list.Add(new KeySizes(0xc0, 0xc0, 0)); if (0xc0 > num) { num = 0xc0; } break; case CapiNative.AlgorithmId.Aes256: list.Add(new KeySizes(0x100, 0x100, 0)); if (0x100 > num) { num = 0x100; } break; } } s_supportedKeySizes = list.ToArray(); s_defaultKeySize = num; } defaultKeySize = s_defaultKeySize; return(s_supportedKeySizes); }
public CapiSymmetricAlgorithm(int blockSize, int feedbackSize, SafeCspHandle provider, SafeCapiKeyHandle key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, EncryptionMode encryptionMode) { Contract.Requires(0 < blockSize && blockSize % 8 == 0); Contract.Requires(0 <= feedbackSize); Contract.Requires(provider != null && !provider.IsInvalid && !provider.IsClosed); Contract.Requires(key != null && !key.IsInvalid && !key.IsClosed); Contract.Ensures(m_provider != null && !m_provider.IsInvalid && !m_provider.IsClosed); m_blockSize = blockSize; m_encryptionMode = encryptionMode; m_paddingMode = paddingMode; m_provider = provider.Duplicate(); m_key = SetupKey(key, ProcessIV(iv, blockSize, cipherMode), cipherMode, feedbackSize); }
public AesCryptoServiceProvider() { Contract.Ensures(m_cspHandle != null && !m_cspHandle.IsInvalid && !m_cspHandle.IsClosed); // On Windows XP the AES CSP has the prototype name, but on newer operating systems it has the // standard name string providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAes; if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1) { providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAesPrototype; } m_cspHandle = CapiNative.AcquireCsp(null, providerName, CapiNative.ProviderType.RsaAes, CapiNative.CryptAcquireContextFlags.VerifyContext, true); // CAPI will not allow feedback sizes greater than 64 bits FeedbackSizeValue = 8; // Get the different AES key sizes supported by this platform, raising an error if there are no // supported key sizes. int defaultKeySize = 0; KeySizes[] keySizes = FindSupportedKeySizes(m_cspHandle, out defaultKeySize); if (keySizes.Length != 0) { Debug.Assert(defaultKeySize > 0, "defaultKeySize > 0"); KeySizeValue = defaultKeySize; } else { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } }
public static extern bool CryptGenRandom(SafeCspHandle hProv, int dwLen, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbBuffer);
public static extern bool CryptCreateHash(SafeCspHandle hProv, AlgorithmId Algid, SafeCapiKeyHandle hKey, int dwFlags, [Out] out SafeCapiHashHandle phHash);
private static KeySizes[] FindSupportedKeySizes(SafeCspHandle csp, out int defaultKeySize) { Contract.Requires(csp != null); Contract.Ensures(Contract.Result <KeySizes[]>() != null); // If this platform has any supported algorithm sizes, then the default key size should be set to a // reasonable value. Contract.Ensures(Contract.Result <KeySizes[]>().Length == 0 || (Contract.ValueAtReturn <int>(out defaultKeySize) > 0 && Contract.ValueAtReturn <int>(out defaultKeySize) % 8 == 0)); if (s_supportedKeySizes == null) { List <KeySizes> keySizes = new List <KeySizes>(); int maxKeySize = 0; // // Enumerate the CSP's supported algorithms to see what key sizes it supports for AES // CapiNative.PROV_ENUMALGS algorithm = CapiNative.GetProviderParameterStruct <CapiNative.PROV_ENUMALGS>(csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.RestartEnumeration); // Translate between CAPI AES algorithm IDs and supported key sizes while (algorithm.aiAlgId != CapiNative.AlgorithmId.None) { switch (algorithm.aiAlgId) { case CapiNative.AlgorithmId.Aes128: keySizes.Add(new KeySizes(128, 128, 0)); if (128 > maxKeySize) { maxKeySize = 128; } break; case CapiNative.AlgorithmId.Aes192: keySizes.Add(new KeySizes(192, 192, 0)); if (192 > maxKeySize) { maxKeySize = 192; } break; case CapiNative.AlgorithmId.Aes256: keySizes.Add(new KeySizes(256, 256, 0)); if (256 > maxKeySize) { maxKeySize = 256; } break; default: break; } algorithm = CapiNative.GetProviderParameterStruct <CapiNative.PROV_ENUMALGS>(csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.None); } s_supportedKeySizes = keySizes.ToArray(); s_defaultKeySize = maxKeySize; } defaultKeySize = s_defaultKeySize; return(s_supportedKeySizes); }
[System.Security.SecuritySafeCritical] // auto-generated public RNGCryptoServiceProvider() { m_cspHandle = CapiNative.AcquireCsp(null, CapiNative.ProviderNames.MicrosoftEnhanced, CapiNative.ProviderType.RsaFull, CapiNative.CryptAcquireContextFlags.VerifyContext); }
internal static SafeCapiKeyHandle ImportSymmetricKey(SafeCspHandle provider, AlgorithmId algorithm, byte[] key) { Contract.Requires(provider != null); Contract.Requires(((int)algorithm & (int)AlgorithmClass.DataEncryption) == (int)AlgorithmClass.DataEncryption); Contract.Requires(key != null); Contract.Ensures(Contract.Result <SafeCapiKeyHandle>() != null && !Contract.Result <SafeCapiKeyHandle>().IsInvalid&& !Contract.Result <SafeCapiKeyHandle>().IsClosed); // // Setup a PLAINTEXTKEYBLOB (v2) which has the following format: // BLOBHEADER hdr // DWORD cbKeySize // BYTE rbgKeyData[] // int blobSize = Marshal.SizeOf(typeof(BLOBHEADER)) + Marshal.SizeOf(typeof(int)) + key.Length; byte[] keyBlob = new byte[blobSize]; unsafe { fixed(byte *pBlob = keyBlob) { BLOBHEADER *pHeader = (BLOBHEADER *)pBlob; pHeader->bType = KeyBlobType.PlainText; pHeader->bVersion = 2; pHeader->reserved = 0; pHeader->aiKeyAlg = algorithm; int *pSize = (int *)(pBlob + Marshal.SizeOf(*pHeader)); *pSize = key.Length; } } Buffer.BlockCopy(key, 0, keyBlob, Marshal.SizeOf(typeof(BLOBHEADER)) + Marshal.SizeOf(typeof(int)), key.Length); // Import the PLAINTEXTKEYBLOB into the CSP SafeCapiKeyHandle importedKey = null; RuntimeHelpers.PrepareConstrainedRegions(); try { if (!UnsafeNativeMethods.CryptImportKey(provider, keyBlob, keyBlob.Length, SafeCapiKeyHandle.InvalidHandle, KeyFlags.Exportable, out importedKey)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } finally { if (importedKey != null && !importedKey.IsInvalid) { importedKey.SetParentCsp(provider); } } return(importedKey); }
public static extern bool CryptGenKey(SafeCspHandle hProv, AlgorithmId Algid, KeyFlags dwFlags, [Out] out SafeCapiKeyHandle phKey);
public static extern bool CryptGetProvParam(SafeCspHandle hProv, ProviderParameter dwParam, IntPtr pbData, [In, Out] ref int pdwDataLen, ProviderParameterFlags dwFlags);
public static extern bool CryptImportKey(SafeCspHandle hProv, [MarshalAs(UnmanagedType.LPArray)] byte[] pbData, int dwDataLen, SafeCapiKeyHandle hPubKey, KeyFlags dwFlags, [Out] out SafeCapiKeyHandle phKey);