protected sealed override byte[] UncheckedTransformFinalBlock(SafeKeyHandle hKey, byte[] currentIv, byte[] inputBuffer, int inputOffset, int inputCount) { byte[] paddedBlock = PadBlock(inputBuffer, inputOffset, inputCount); byte[] output = new byte[paddedBlock.Length]; hKey.BCryptEncrypt(paddedBlock, 0, paddedBlock.Length, currentIv, output, 0, output.Length); return output; }
public static extern SECURITY_STATUS NCryptCreatePersistedKey( SafeProviderHandle hProvider, out SafeKeyHandle phKey, string pszAlgId, string pszKeyName = null, LegacyKeySpec dwLegacyKeySpec = LegacyKeySpec.None, NCryptCreatePersistedKeyFlags dwFlags = NCryptCreatePersistedKeyFlags.None);
private byte[] _currentIv; // CNG mutates this with the updated IV for the next stage on each Encrypt/Decrypt call. // The base IV holds a copy of the original IV for Reset(), until it is cleared by Dispose(). public TripleDesCngCipher(CipherMode cipherMode, int blockSizeInBytes, byte[] key, byte[] iv, bool encrypting) : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) { _encrypting = encrypting; if (IV != null) { _currentIv = new byte[IV.Length]; } SafeAlgorithmHandle hAlg = GetCipherAlgorithm(cipherMode); _hKey = hAlg.BCryptImportKey(key); Reset(); }
protected sealed override int UncheckedTransformBlock(SafeKeyHandle hKey, byte[] currentIv, byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { // // If we're decrypting, it's possible to be called with the last blocks of the data, and then // have TransformFinalBlock called with an empty array. Since we don't know if this is the case, // we won't decrypt the last block of the input until either TransformBlock or // TransformFinalBlock is next called. // // We don't need to do this for PaddingMode.None because there is no padding to strip, and // we also don't do this for PaddingMode.Zeros since there is no way for us to tell if the // zeros at the end of a block are part of the plaintext or the padding. // int decryptedBytes = 0; if (DepaddingRequired) { // If we have data saved from a previous call, decrypt that into the output first if (_heldoverCipher != null) { int depadDecryptLength = DecryptInPlace(hKey, currentIv, _heldoverCipher, 0, _heldoverCipher.Length); Buffer.BlockCopy(_heldoverCipher, 0, outputBuffer, outputOffset, depadDecryptLength); Array.Clear(_heldoverCipher, 0, _heldoverCipher.Length); outputOffset += depadDecryptLength; decryptedBytes += depadDecryptLength; } else { _heldoverCipher = new byte[InputBlockSize]; } // Copy the last block of the input buffer into the depad buffer Debug.Assert(inputCount >= _heldoverCipher.Length, "inputCount >= _heldoverCipher.Length"); Buffer.BlockCopy(inputBuffer, inputOffset + inputCount - _heldoverCipher.Length, _heldoverCipher, 0, _heldoverCipher.Length); inputCount -= _heldoverCipher.Length; Debug.Assert(inputCount % InputBlockSize == 0, "Did not remove whole blocks for depadding"); } // If after reserving the depad buffer there's still data to decrypt, make a copy of that in the output buffer to work on. if (inputCount > 0) { Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount); decryptedBytes += DecryptInPlace(hKey, currentIv, outputBuffer, outputOffset, inputCount); } return decryptedBytes; }
private byte[] _currentIv; // CNG mutates this with the updated IV for the next stage on each Encrypt/Decrypt call. // The base IV holds a copy of the original IV for Reset(), until it is cleared by Dispose(). public CngCipher(SafeAlgorithmHandle algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, byte[] iv, bool encrypting) : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) { Debug.Assert(algorithm != null); _encrypting = encrypting; if (IV != null) { _currentIv = new byte[IV.Length]; } _hKey = algorithm.BCryptImportKey(key); Reset(); }
protected override void Dispose(bool disposing) { if (disposing) { SafeKeyHandle hKey = _hKey; _hKey = null; if (hKey != null) { hKey.Dispose(); } SafeProvHandle hProvider = _hProvider; _hProvider = null; if (hProvider != null) { hProvider.Dispose(); } } base.Dispose(disposing); }
public BasicSymmetricCipherCsp(int algId, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, bool addNoSaltFlag, byte[] iv, bool encrypting) : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) { _encrypting = encrypting; _hProvider = AcquireSafeProviderHandle(); _hKey = ImportCspBlob(_hProvider, algId, key, addNoSaltFlag); SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_MODE, (int)cipherMode); byte[] currentIv = cipherMode.GetCipherIv(iv); if (currentIv != null) { SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_IV, currentIv); } if (effectiveKeyLength != 0) { SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_EFFECTIVE_KEYLEN, effectiveKeyLength); } }
private byte[] _currentIv; // CNG mutates this with the updated IV for the next stage on each Encrypt/Decrypt call. // The base IV holds a copy of the original IV for Reset(), until it is cleared by Dispose(). public BasicSymmetricCipherBCrypt(SafeAlgorithmHandle algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, byte[] iv, bool encrypting) : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) { Debug.Assert(algorithm != null); _encrypting = encrypting; if (IV != null) { _currentIv = new byte[IV.Length]; } _hKey = algorithm.BCryptImportKey(key); if (effectiveKeyLength != 0) { Cng.SetEffectiveKeyLength(_hKey, effectiveKeyLength); } Reset(); }
protected override void Dispose(bool disposing) { if (disposing) { SafeKeyHandle hKey = _hKey; _hKey = null; if (hKey != null) { hKey.Dispose(); } byte[] currentIv = _currentIv; _currentIv = null; if (currentIv != null) { Array.Clear(currentIv, 0, currentIv.Length); } } base.Dispose(disposing); }
public static byte[] BCryptExportKey(SafeKeyHandle key, SafeKeyHandle exportKey, string blobType) { int lengthRequired; exportKey = exportKey ?? SafeKeyHandle.NullHandle; BCryptExportKey( key, exportKey, blobType, null, 0, out lengthRequired, 0).ThrowOnError(); byte[] keyBuffer = new byte[lengthRequired]; BCryptExportKey( key, exportKey, AsymmetricKeyBlobTypes.EccPublic, keyBuffer, keyBuffer.Length, out lengthRequired, 0).ThrowOnError(); return keyBuffer; }
public static extern SECURITY_STATUS NCryptSecretAgreement( SafeKeyHandle hPrivKey, SafeKeyHandle hPubKey, out SafeSecretHandle phSecret, NCryptSecretAgreementFlags dwFlags = NCryptSecretAgreementFlags.None);
private static extern bool _CryptImportKey(SafeProvHandle hProv, byte[] pbData, int dwDataLen, SafeKeyHandle hPubKey, int dwFlags, out SafeKeyHandle phKey);
/// <summary> /// Helper for Export CSP /// </summary> internal static byte[] ExportKeyBlob(bool includePrivateParameters, SafeKeyHandle safeKeyHandle) { VerifyValidHandle(safeKeyHandle); byte[] pbRawData = null; int cbRawData = 0; int dwBlobType = includePrivateParameters ? PRIVATEKEYBLOB : PUBLICKEYBLOB; if (!Interop.CryptExportKey(safeKeyHandle, SafeKeyHandle.InvalidHandle, dwBlobType, 0, null, ref cbRawData)) { throw new CryptographicException(SR.Format(SR.CryptExportKey_Failed, Convert.ToString(GetErrorCode()))); } pbRawData = new byte[cbRawData]; if (!Interop.CryptExportKey(safeKeyHandle, SafeKeyHandle.InvalidHandle, dwBlobType, 0, pbRawData, ref cbRawData)) { throw new CryptographicException(SR.Format(SR.CryptExportKey_Failed, Convert.ToString(GetErrorCode()))); } return pbRawData; }
public static unsafe extern SECURITY_STATUS NCryptDecrypt( SafeKeyHandle hKey, byte* pbInput, int cbInput, void* pPaddingInfo, byte* pbOutput, int cbOutput, out int pcbResult, NCryptEncryptFlags dwFlags);
public static bool CryptImportKey( SafeProvHandle hProv, byte[] pbData, int dwDataLen, SafeKeyHandle hPubKey, int dwFlags, out SafeKeyHandle phKey) { bool response = _CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, out phKey); phKey.SetParent(hProv); return response; }
public static extern bool CryptSetKeyParam(SafeKeyHandle hKey, int dwParam, byte[] pbData, int dwFlags);
internal static partial bool CryptCreateHash( SafeProvHandle hProv, int Algid, SafeKeyHandle hKey, CryptCreateHashFlags dwFlags, out SafeHashHandle phHash);
public static bool CryptGetUserKey( SafeProvHandle safeProvHandle, int dwKeySpec, out SafeKeyHandle safeKeyHandle) { bool response = _CryptGetUserKey(safeProvHandle, dwKeySpec, out safeKeyHandle); safeKeyHandle.SetParent(safeProvHandle); return response; }
internal static extern bool CryptGetUserKey(SafeProvHandle hProv, int dwKeySpec, out SafeKeyHandle phUserKey);
public static extern SECURITY_STATUS NCryptOpenKey( SafeProviderHandle hProvider, out SafeKeyHandle phKey, string pszKeyName, LegacyKeySpec dwLegacyKeySpec, NCryptOpenKeyFlags dwFlags = NCryptOpenKeyFlags.None);
public static extern SECURITY_STATUS NCryptDeleteKey( SafeKeyHandle hKey, NCryptDeleteKeyFlags dwFlags = NCryptDeleteKeyFlags.None);
internal AndroidCertificatePal(SafeX509Handle handle, SafeKeyHandle privateKey) { _cert = handle; _privateKey = privateKey; }
public static extern bool CryptSetKeyParam(SafeKeyHandle safeKeyHandle, int dwParam, ref int pdw, int dwFlags);
private static extern bool _CryptCreateHash(SafeProvHandle hProv, int algId, SafeKeyHandle hKey, CryptCreateHashFlags dwFlags, out SafeHashHandle phHash);
/// <summary> /// Retrieves the handle for user public / private key pair. /// </summary> internal static int GetUserKey(SafeProvHandle safeProvHandle, int keySpec, out SafeKeyHandle safeKeyHandle) { int hr = S_OK; VerifyValidHandle(safeProvHandle); if (!Interop.CryptGetUserKey(safeProvHandle, keySpec, out safeKeyHandle)) { hr = GetErrorCode(); } if (hr == S_OK) { safeKeyHandle.KeySpec = keySpec; } return hr; }
public static extern bool CryptVerifySignature(SafeHashHandle hHash, byte[] pbSignature, int dwSigLen, SafeKeyHandle hPubKey, String sDescription, CryptSignAndVerifyHashFlags dwFlags);
/// <summary> ///Method helps get the different key properties /// </summary> /// <param name="safeKeyHandle">Key handle</param> /// <param name="dwKeyParam"> Key property you want to get</param> /// <returns>Returns the key property</returns> internal static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam) { byte[] pb = null; int cb = 0; VerifyValidHandle(safeKeyHandle); //This will throw if handle is invalid switch (keyParam) { case Constants.CLR_KEYLEN: { //ToDO : Check if we should use silent flag here as this might not run //downlevel so we might want to use silent flag // Some Csp's may pop up a UI here since we don't use CRYPT_SILENT flag // which is not supported in downlevel platforms if (!Interop.CryptGetKeyParam(safeKeyHandle, (int)CryptGetKeyParamQueryType.KP_KEYLEN, null, ref cb, 0)) { throw new CryptographicException(SR.Format(SR.CryptGetKeyParam_Failed, Convert.ToString(GetErrorCode()))); } pb = new byte[cb]; if (!Interop.CryptGetKeyParam(safeKeyHandle, (int)CryptGetKeyParamQueryType.KP_KEYLEN, pb, ref cb, 0)) { throw new CryptographicException(SR.Format(SR.CryptGetKeyParam_Failed, Convert.ToString(GetErrorCode()))); } break; } case Constants.CLR_PUBLICKEYONLY: { pb = new byte[1]; pb[0] = safeKeyHandle.PublicOnly ? (byte)1 : (byte)0; break; } case Constants.CLR_ALGID: { // returns the algorithm ID for the key if (!Interop.CryptGetKeyParam(safeKeyHandle, (int)CryptGetKeyParamQueryType.KP_ALGID, null, ref cb, 0)) { throw new CryptographicException(SR.Format(SR.CryptGetKeyParam_Failed, Convert.ToString(GetErrorCode()))); } pb = new byte[cb]; if (!Interop.CryptGetKeyParam(safeKeyHandle, (int)CryptGetKeyParamQueryType.KP_ALGID, pb, ref cb, 0)) { throw new CryptographicException(SR.Format(SR.CryptGetKeyParam_Failed, Convert.ToString(GetErrorCode()))); } break; } default: { Debug.Assert(false); break; } } return pb; }
public static bool CryptGenKey( SafeProvHandle safeProvHandle, int algId, int dwFlags, out SafeKeyHandle safeKeyHandle) { bool response = _CryptGenKey(safeProvHandle, algId, dwFlags, out safeKeyHandle); safeKeyHandle.SetParent(safeProvHandle); return response; }
//--------------------------------------------------------------------------------------- // // Encrypt a symmetric key using the public key in pKeyContext // // Arguments: // safeKeyHandle [in] Key handle // pbKey - [in] symmetric key to encrypt // cbKey - size, in bytes, of pbKey // fOAEP - TRUE to use OAEP padding, FALSE to use PKCS #1 type 2 padding // ohRetEncryptedKey - [out] byte array holding the encrypted key // // Notes: // The returned value in ohRetEncryptedKey is byte-reversed from the version CAPI gives us. This is for // compatibility with previous releases of the CLR and other RSA implementations. // internal static void EncryptKey(SafeKeyHandle safeKeyHandle, byte[] pbKey, int cbKey, bool foep, ref byte[] pbEncryptedKey) { VerifyValidHandle(safeKeyHandle); if (null == pbKey) { throw new CryptographicException(SR.Format(SR.Argument_InvalidValue, "pbKey is null")); } if (cbKey < 0) { throw new CryptographicException(SR.Format(SR.Argument_InvalidValue, "cbKey is less than 0")); } int dwEncryptFlags = foep ? (int)CryptDecryptFlags.CRYPT_OAEP : 0; // Figure out how big the encrypted key will be int cbEncryptedKey = cbKey; if (!Interop.CryptEncrypt(safeKeyHandle, SafeHashHandle.InvalidHandle, true, dwEncryptFlags, null, ref cbEncryptedKey, cbEncryptedKey)) { throw new CryptographicException(SR.Format(SR.CryptEncrypt_Failed, Convert.ToString(GetErrorCode()))); } // pbData is an in/out buffer for CryptEncrypt. allocate space for the encrypted key, and copy the // plaintext key into that space. Since encrypted keys will have padding applied, the size of the encrypted // key should always be larger than the plaintext key, so use that to determine the buffer size. Debug.Assert(cbEncryptedKey >= cbKey); pbEncryptedKey = new byte[cbEncryptedKey]; Buffer.BlockCopy(pbKey, 0, pbEncryptedKey, 0, cbKey); // Encrypt for real - the last parameter is the total size of the in/out buffer, while the second to last // parameter specifies the size of the plaintext to encrypt. if (!Interop.CryptEncrypt(safeKeyHandle, SafeHashHandle.InvalidHandle, true, dwEncryptFlags, pbEncryptedKey, ref cbKey, cbEncryptedKey)) { } Debug.Assert(cbKey == cbEncryptedKey); Array.Reverse(pbEncryptedKey); }
public static bool CryptCreateHash( SafeProvHandle hProv, int algId, SafeKeyHandle hKey, CryptCreateHashFlags dwFlags, out SafeHashHandle phHash) { bool response = _CryptCreateHash(hProv, algId, hKey, dwFlags, out phHash); phHash.SetParent(hProv); return response; }
public static extern bool CryptGetKeyParam( SafeKeyHandle hKey, CryptGetKeyParamFlags dwParam, byte[] pbData, ref int pdwDataLen, int dwFlags);
/// <summary> /// Generates the key if provided CSP handle is valid /// </summary> internal static int GenerateKey(SafeProvHandle safeProvHandle, int algID, int flags, uint keySize, out SafeKeyHandle safeKeyHandle) { int hr = S_OK; VerifyValidHandle(safeProvHandle); int capiFlags = (int)((uint)MapCspKeyFlags(flags) | ((uint)keySize << 16)); if (!Interop.CryptGenKey(safeProvHandle, algID, capiFlags, out safeKeyHandle)) { hr = GetErrorCode(); } if (hr != S_OK) { throw new CryptographicException(SR.Format(SR.CryptGenKey_Failed, Convert.ToString(GetErrorCode()))); } safeKeyHandle.KeySpec = algID; return hr; }
public static object Recover() { List <RecoveredBrowserAccount> list = new List <RecoveredBrowserAccount>(); string name = @"Software\DownloadManager\Passwords\"; IntPtr hKey = new IntPtr(-2147483647); try { RegistryKey key = Registry.CurrentUser.OpenSubKey(name); if (key.GetSubKeyNames().Length == 0) { return(list); } foreach (string str3 in key.GetSubKeyNames()) { RegistryKey key2 = key.OpenSubKey(str3); SafeKeyHandle phkResult = null; int num2 = NativeMethods.RegOpenKeyEx(hKey, name + str3, 0, 0x20019, out phkResult); byte[] data = new byte[0x101]; byte[] buffer = new byte[0x101]; int type = 0; int dataSize = 0x100; num2 = NativeMethods.RegQueryValueEx(phkResult, "User", 0, out type, data, ref dataSize); dataSize = 0; type = 0x100; num2 = NativeMethods.RegQueryValueEx(phkResult, "EncPassword", 0, out dataSize, buffer, ref type); RecoveredBrowserAccount item = new RecoveredBrowserAccount { URL = str3 }; int num = 0; int num8 = data.Length - 1; for (int i = 0; i <= num8; i++) { if (data[i] == 0) { break; } num++; } data = (byte[])Utils.CopyArray((Array)data, new byte[(num - 1) + 1]); item.UserName = Encoding.Default.GetString(data); num = 0; string str2 = null; int num9 = buffer.Length - 1; for (int j = 0; j <= num9; j++) { if (buffer[j] == 0) { break; } str2 = str2 + Conversions.ToString(Strings.ChrW(buffer[j] ^ 15)); } item.Password = str2; item.Browser = "Internet Download Manager"; list.Add(item); } } catch (Exception exception1) { ProjectData.SetProjectError(exception1); Exception exception = exception1; ProjectData.ClearProjectError(); } return(list); }
//--------------------------------------------------------------------------------------- // // Decrypt a symmetric key using the private key in pKeyContext // // Arguments: // pKeyContext - private key used for decrypting pbEncryptedKey // pbEncryptedKey - [in] encrypted symmetric key // cbEncryptedKey - size, in bytes, of pbEncryptedKey // fOAEP - TRUE to use OAEP padding, FALSE to use PKCS #1 type 2 padding // ohRetDecryptedKey - [out] decrypted key // // Notes: // pbEncryptedKey is byte-reversed from the format that CAPI expects. This is for compatibility with // previous CLR versions and other RSA implementations. // // This method is the target of the System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey QCall // // static internal static void DecryptKey(SafeKeyHandle safeKeyHandle, byte[] encryptedData, int encryptedDataLength, bool fOAEP, out byte[] decryptedData) { VerifyValidHandle(safeKeyHandle); if (null == encryptedData) { throw new CryptographicException(SR.Format(SR.Argument_InvalidValue, "Encrypted Data is null")); } if (encryptedDataLength < 0) { throw new CryptographicException(SR.Format(SR.Argument_InvalidValue, "Encrypted data length is less than 0")); } byte[] dataTobeDecrypted = new byte[encryptedDataLength]; Buffer.BlockCopy(encryptedData, 0, dataTobeDecrypted, 0, encryptedDataLength); Array.Reverse(dataTobeDecrypted); //ToDO: Check is this is really needed? To be confirmed with tests int dwFlags = fOAEP ? (int)CryptDecryptFlags.CRYPT_OAEP : 0; int decryptedDataLength = encryptedDataLength; if (!Interop.CryptDecrypt(safeKeyHandle, SafeHashHandle.InvalidHandle, true, dwFlags, dataTobeDecrypted, ref decryptedDataLength)) { int ErrCode = GetErrorCode(); // If we're using OAEP mode and we received an NTE_BAD_FLAGS error, then OAEP is not supported on // this platform (XP+ only). Throw a generic cryptographic exception if we failed to decrypt OAEP // padded data in order to prevent a chosen ciphertext attack. We will allow NTE_BAD_KEY out, since // that error does not relate to the padding. Otherwise just throw a cryptographic exception based on // the error code. if ((uint)((uint)dwFlags & (uint)CryptDecryptFlags.CRYPT_OAEP) == (uint)CryptDecryptFlags.CRYPT_OAEP && (uint)ErrCode != (uint)CryptKeyError.NTE_BAD_KEY) { if ((uint)ErrCode == (uint)CryptKeyError.NTE_BAD_FLAGS) { throw new CryptographicException("Cryptography_OAEP_XPPlus_Only"); } else { throw new CryptographicException("Cryptography_OAEPDecoding"); } } else { throw new CryptographicException(SR.Format(SR.CryptDecrypt_Failed, Convert.ToString(ErrCode))); } } decryptedData = new byte[decryptedDataLength]; Buffer.BlockCopy(dataTobeDecrypted, 0, decryptedData, 0, decryptedDataLength); return; }
public static extern SECURITY_STATUS NCryptFinalizeKey( SafeKeyHandle hKey, NCryptFinalizeKeyFlags dwFlags = NCryptFinalizeKeyFlags.None);
/// <summary> /// Helper for Import CSP /// </summary> internal static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, byte[] keyBlob, out SafeKeyHandle safeKeyHandle) { // Compat note: This isn't the same check as the one done by the CLR _ImportCspBlob QCall, // but this does match the desktop CLR behavior and the only scenarios it // affects are cases where a corrupt blob is passed in. bool isPublic = keyBlob.Length > 0 && keyBlob[0] == CapiHelper.PUBLICKEYBLOB; int dwCapiFlags = MapCspKeyFlags((int)flags); if (isPublic) { dwCapiFlags &= ~(int)(CryptGenKeyFlags.CRYPT_EXPORTABLE); } SafeKeyHandle hKey; if (!Interop.CryptImportKey(saveProvHandle, keyBlob, keyBlob.Length, SafeKeyHandle.InvalidHandle, dwCapiFlags, out hKey)) { int hr = Marshal.GetHRForLastWin32Error(); hKey.Dispose(); throw hr.ToCryptographicException(); } hKey.PublicOnly = isPublic; safeKeyHandle = hKey; return; }
protected sealed override int UncheckedTransformBlock(SafeKeyHandle hKey, byte[] currentIv, byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { int numBytesWritten = hKey.BCryptEncrypt(inputBuffer, inputOffset, inputCount, currentIv, outputBuffer, outputOffset, outputBuffer.Length); return(numBytesWritten); }
/// <summary> /// Helper for DSACryptoServiceProvider.ExportParameters() /// </summary> internal static DSAParameters ToDSAParameters(this byte[] cspBlob, bool includePrivateParameters, SafeKeyHandle safeKeyHandle) { try { using (var ms = new MemoryStream(cspBlob)) using (var br = new BinaryReader(ms)) { byte bVersion; ReadKeyBlobHeader(br, out bVersion); DSAParameters dsaParameters = new DSAParameters(); if (bVersion > 2) { // We need to read a key blob (DSSPUBKEY_VER3 or DSSPRIVKEY_VER3) as follows: // DWORD magic // DWORD bitlenP // DWORD bitlenQ // DWORD bitlenJ // DWORD bitlenX (if private) // DWORD counter (DSSSEED) // BYTE[20] seed (DSSSEED) // BYTE[lenP] P // BYTE[lenQ] Q // BYTE[lenP] G // BYTE[lenJ] J (optional) // BYTE[lenP] Y // BYTE[lenX] X (if private) int magic = br.ReadInt32(); // Expected to be DSS_PUB_MAGIC_VER3 or DSS_PRIV_MAGIC_VER3 int lenP = (br.ReadInt32() + 7) / 8; int lenQ = (br.ReadInt32() + 7) / 8; int lenJ = (br.ReadInt32() + 7) / 8; int lenX = 0; if (includePrivateParameters) { lenX = (br.ReadInt32() + 7) / 8; } ReadDSSSeed(dsaParameters, br, true); dsaParameters.P = br.ReadReversed(lenP); dsaParameters.Q = br.ReadReversed(lenQ); dsaParameters.G = br.ReadReversed(lenP); if (lenJ > 0) { dsaParameters.J = br.ReadReversed(lenJ); } dsaParameters.Y = br.ReadReversed(lenP); if (includePrivateParameters) { dsaParameters.X = br.ReadReversed(lenX); } } else { // We need to read a key blob as follows: // DWORD magic (DSSPUBKEY) // DWORD bitlen (DSSPUBKEY) // BYTE[len] P // BYTE[DSS_Q_LEN] Q // BYTE[len] G // BYTE[20] X (if private) // BYTE[len] Y (if public) // DWORD counter (DSSSEED) // BYTE[20] seed (DSSSEED) int magic = br.ReadInt32(); // Expected to be DSS_MAGIC or DSS_PRIVATE_MAGIC int len = (br.ReadInt32() + 7) / 8; dsaParameters.P = br.ReadReversed(len); dsaParameters.Q = br.ReadReversed(DSS_Q_LEN); dsaParameters.G = br.ReadReversed(len); long keyLocation = 0; if (includePrivateParameters) { // Save the position of the stream for later access to Y. keyLocation = br.BaseStream.Position; dsaParameters.X = br.ReadReversed(20); } else dsaParameters.Y = br.ReadReversed(len); ReadDSSSeed(dsaParameters, br, false); if (includePrivateParameters) { // Since DSSPUBKEY key is used for both public and private keys, we got X // but not Y. To get Y, do another export and ask for public key blob. byte[] cspPublicBlob = ExportKeyBlob(false, safeKeyHandle); using (var msPublicBlob = new MemoryStream(cspPublicBlob)) using (var brPublicBlob = new BinaryReader(msPublicBlob)) { brPublicBlob.BaseStream.Position = keyLocation; dsaParameters.Y = brPublicBlob.ReadReversed(len); } } } return dsaParameters; } } catch (EndOfStreamException) { // For compat reasons, we throw an E_FAIL CrytoException if CAPI returns a smaller blob than expected. // For compat reasons, we ignore the extra bits if the CAPI returns a larger blob than expected. throw E_FAIL.ToCryptographicException(); } }
public static extern bool CryptEncrypt(SafeKeyHandle safeKeyHandle, SafeHashHandle safeHashHandle, bool Final, int dwFlags, byte[] pbData, ref int pdwDataLen, int dwBufLen);
public static extern bool CryptExportKey(SafeKeyHandle hKey, SafeKeyHandle hExpKey, int dwBlobType, int dwFlags, [In, Out] byte[] pbData, ref int dwDataLen);
/// <summary> /// Completes a public/private key pair. /// </summary> /// <param name="keyHandle">The handle of the key to complete. This handle is obtained by calling the BCryptGenerateKeyPair function.</param> /// <remarks> /// The key cannot be used until this function has been called. /// After this function has been called, the BCryptSetProperty function /// can no longer be used for this key. /// </remarks> public static void BCryptFinalizeKeyPair(SafeKeyHandle keyHandle) { var error = BCryptFinalizeKeyPair(keyHandle, 0); error.ThrowOnError(); }
public static extern unsafe SECURITY_STATUS NCryptExportKey( SafeKeyHandle hKey, SafeKeyHandle hExportKey, string pszBlobType, NCryptBufferDesc* pParameterList, byte[] pbOutput, int cbOutput, out int pcbResult, NCryptExportKeyFlags dwFlags = NCryptExportKeyFlags.None);
private static extern NTSTATUS BCryptImportKey(SafeAlgorithmHandle hAlgorithm, IntPtr hImportKey, string pszBlobType, out SafeKeyHandle hKey, IntPtr pbKeyObject, int cbKeyObject, byte[] pbInput, int cbInput, int dwFlags);