private static extern bool CryptUnprotectData(ref DATA_BLOB pCipherText, ref string pszDescription, ref DATA_BLOB pEntropy, IntPtr pReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPrompt, int dwFlags, ref DATA_BLOB pPlainText);
private static byte[] _DecryptBlock(byte[] encryptedBlock) { const int ENTROPY_LENGTH = 0x86; const string ENTROPY_DATA = "Software"; //Really? *Really*? var entropyData = new byte[ENTROPY_LENGTH]; //Create the prompt structure for CryptUnprotectData CRYPTPROTECT_PROMPTSTRUCT prompt = new CRYPTPROTECT_PROMPTSTRUCT(); prompt.cbSize = Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT)); prompt.dwPromptFlags = 0; prompt.hwndApp = IntPtr.Zero; prompt.szPrompt = null; //Build the entropy structure DATA_BLOB entropy = new DATA_BLOB(); entropy.cbData = entropyData.Length; Array.Copy(Encoding.ASCII.GetBytes(ENTROPY_DATA), 0, entropyData, 0, ENTROPY_DATA.Length); IntPtr ptrEntropy = Marshal.AllocHGlobal(entropyData.Length); entropyData[0x2B] = 0x01; //anti-debugging magic entropyData[0x43] = 0x05; Marshal.Copy(entropyData, 0, ptrEntropy, entropyData.Length); entropy.pbData = ptrEntropy; //Build the cipher text structure DATA_BLOB cipherText = new DATA_BLOB(); IntPtr ptrCipher = Marshal.AllocHGlobal(encryptedBlock.Length); Marshal.Copy(encryptedBlock, 0, ptrCipher, encryptedBlock.Length); cipherText.cbData = encryptedBlock.Length; cipherText.pbData = ptrCipher; //Do the decryption DATA_BLOB plainText = new DATA_BLOB(); var description = String.Empty; //Not using a description if (!CryptUnprotectData(ref cipherText, ref description, ref entropy, IntPtr.Zero, ref prompt, 0, ref plainText)) { throw new InvalidOperationException("DPAPI decryption error: " + Marshal.GetLastWin32Error().ToString("X8")); } //Get the decrypted data into our object var decrypted = new byte[plainText.cbData]; Marshal.Copy(plainText.pbData, decrypted, 0, plainText.cbData); //Free everything up LocalFree(plainText.pbData); Marshal.FreeHGlobal(ptrEntropy); Marshal.FreeHGlobal(ptrCipher); return(decrypted); }
private static byte[] _DecryptBlock(byte[] encryptedBlock) { const int ENTROPY_LENGTH = 0x86; const string ENTROPY_DATA = "Software"; //Really? *Really*? var entropyData = new byte[ENTROPY_LENGTH]; //Create the prompt structure for CryptUnprotectData CRYPTPROTECT_PROMPTSTRUCT prompt = new CRYPTPROTECT_PROMPTSTRUCT(); prompt.cbSize = Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT)); prompt.dwPromptFlags = 0; prompt.hwndApp = IntPtr.Zero; prompt.szPrompt = null; //Build the entropy structure DATA_BLOB entropy = new DATA_BLOB(); entropy.cbData = entropyData.Length; Array.Copy(Encoding.ASCII.GetBytes(ENTROPY_DATA), 0, entropyData, 0, ENTROPY_DATA.Length); IntPtr ptrEntropy = Marshal.AllocHGlobal(entropyData.Length); entropyData[0x2B] = 0x01; //anti-debugging magic entropyData[0x43] = 0x05; Marshal.Copy(entropyData, 0, ptrEntropy, entropyData.Length); entropy.pbData = ptrEntropy; //Build the cipher text structure DATA_BLOB cipherText = new DATA_BLOB(); IntPtr ptrCipher = Marshal.AllocHGlobal(encryptedBlock.Length); Marshal.Copy(encryptedBlock, 0, ptrCipher, encryptedBlock.Length); cipherText.cbData = encryptedBlock.Length; cipherText.pbData = ptrCipher; //Do the decryption DATA_BLOB plainText = new DATA_BLOB(); var description = String.Empty; //Not using a description if (!CryptUnprotectData(ref cipherText, ref description, ref entropy, IntPtr.Zero, ref prompt, 0, ref plainText)) throw new InvalidOperationException("DPAPI decryption error: " + Marshal.GetLastWin32Error().ToString("X8")); //Get the decrypted data into our object var decrypted = new byte[plainText.cbData]; Marshal.Copy(plainText.pbData, decrypted, 0, plainText.cbData); //Free everything up LocalFree(plainText.pbData); Marshal.FreeHGlobal(ptrEntropy); Marshal.FreeHGlobal(ptrCipher); return decrypted; }