internal static extern int CryptUnprotectData(ref DataBlob pDataIn, IntPtr ppszDataDescr, ref DataBlob pOptionalEntropy, IntPtr pvReserved, IntPtr pPromptStruct, int dwFlags, ref DataBlob pDataOut);
internal static extern IntPtr CertFindDataBlobCertificateInStore(IntPtr hCertStore, int dwCertEncodingType, int dwFindFlags, int dwFindType, ref DataBlob pvFindPara, IntPtr pPrevCertContext);
internal static extern int CertSaveStore(IntPtr hCertStore, int dwMsgAndCertEncodingType, int dwSaveAs, int dwSaveTo, ref DataBlob pvSaveToPara, int dwFlags);
internal static extern int CryptSetKeyParam(int hKey, int dwParam, ref DataBlob pbData, int dwFlags);
internal static extern int PFXExportCertStoreEx(IntPtr hStore, ref DataBlob pPFX, string szPassword, IntPtr pvReserved, int dwFlags);
internal static extern int PFXVerifyPassword(ref DataBlob pPFX, string szPassword, int dwFlags);
internal static extern int PFXIsPFXBlob(ref DataBlob pPFX);
internal static extern IntPtr PFXImportCertStore(ref DataBlob pPFX, string szPassword, int dwFlags);
internal static extern IntPtr CertOpenStoreData(IntPtr lpszStoreProvider, int dwMsgAndCertEncodingType, IntPtr hCryptProv, int dwFlags, ref DataBlob pvPara);
/// <summary> /// Decrypts data that has been encrypted with the <see cref="ProtectData"/> method. /// </summary> /// <param name="data">The data to decrypt.</param> /// <param name="offset">The zero-based position in the <i>data</i> parameter at which to begin decrypting.</param> /// <param name="size">The number of bytes to decrypt.</param> /// <param name="entropy">Additional entropy to use during the decryption process. This parameter can be set to null.</param> /// <exception cref="ArgumentNullException"><i>data</i> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="ArgumentException">The specified <i>offset</i> or <i>size</i> exceeds the size of buffer.</exception> /// <exception cref="CryptographicException">An error occurs during the encryption process. Under some circumstances, Microsoft cryptographic service providers may not allow encryption when used in France. This may occur on down-level platforms such as Windows 98 and Windows NT 4.0, depending on the system's configuration and the version of the CSPs.</exception> /// <returns>The decrypted data.</returns> /// <remarks>The entropy used during decryption must be the same as the entropy used during encryption.</remarks> public byte[] UnprotectData(byte[] data, int offset, int size, byte[] entropy) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (data == null) throw new ArgumentNullException(); if (offset < 0 || offset + size > data.Length) throw new ArgumentException(); DataBlob input = new DataBlob(); DataBlob entr = new DataBlob(); DataBlob output = new DataBlob(); try { // initialize input structure input.cbData = size; input.pbData = Marshal.AllocHGlobal(size); Marshal.Copy(data, offset, input.pbData, size); // initialize entropy structure if (entropy == null) { entr.cbData = 0; entr.pbData = IntPtr.Zero; } else { entr.cbData = entropy.Length; entr.pbData = Marshal.AllocHGlobal(entr.cbData); Marshal.Copy(entropy, 0, entr.pbData, entr.cbData); } // initialize output structure output.cbData = 0; output.pbData = IntPtr.Zero; // call the function and check for errors int flags = 0; if (!Environment.UserInteractive) flags = flags | SecurityConstants.CRYPTPROTECT_UI_FORBIDDEN; if (SspiProvider.CryptUnprotectData(ref input, IntPtr.Zero, ref entr, IntPtr.Zero, IntPtr.Zero, flags, ref output) == 0 || output.pbData == IntPtr.Zero) throw new CryptographicException("The data could not be unprotected."); byte[] ret = new byte[output.cbData]; Marshal.Copy(output.pbData, ret, 0, output.cbData); return ret; } finally { if (input.pbData != IntPtr.Zero) Marshal.FreeHGlobal(input.pbData); if (entr.pbData != IntPtr.Zero) Marshal.FreeHGlobal(entr.pbData); if (output.pbData != IntPtr.Zero) Marshal.FreeHGlobal(output.pbData); } }