public void Constructor(DPAPIKeyType keyType)
        {
            string plainText = GenerateClearText();

            var engine = new DPAPIEngine(keyType);

            string encrypted = engine.Encrypt(plainText);

            string decrypted = engine.Decrypt(encrypted);

            Assert.NotEqual(plainText, encrypted);
            Assert.NotEqual(encrypted, decrypted);
            Assert.Equal(plainText, decrypted);
        }
        public void SetEntropyString(DPAPIKeyType keyType)
        {
            string plainText = GenerateClearText();

            var engine = new DPAPIEngine(keyType)
                .SetEntropy("myEntropy");

            string encrypted = engine.Encrypt(plainText);

            string decrypted = engine.Decrypt(encrypted);

            Assert.NotEqual(plainText, encrypted);
            Assert.NotEqual(encrypted, decrypted);
            Assert.Equal(plainText, decrypted);
        }
        public void SetEntropySecureString(DPAPIKeyType keyType)
        {
            string plainText = GenerateClearText();

            var entropy = new SecureString();
            foreach (char ch in "myEntropy")
            {
                entropy.AppendChar(ch);
            }

            var engine = new DPAPIEngine(keyType)
                .SetEntropy(entropy);

            string encrypted = engine.Encrypt(plainText);

            string decrypted = engine.Decrypt(encrypted);

            Assert.NotEqual(plainText, encrypted);
            Assert.NotEqual(encrypted, decrypted);
            Assert.Equal(plainText, decrypted);
        }
 ///<summary>
 /// Initializes a new instance of the <see cref="DPAPIEngine"/> object.
 ///</summary>
 ///<param name="keyType">Defines the method (<see cref="DPAPIKeyType"/>) to use for encryption/decryption.</param>
 public DPAPIEngine(DPAPIKeyType keyType)
 {
     KeyType = keyType;
     Entropy = ToSecureString(string.Empty);
     Encoding = Encoding.Default;
 }
        private static byte[] DPAPIEncrypt(DPAPIKeyType keyType, byte[] plainTextBytes, byte[] entropyBytes)
        {
            // Create Null BLOBs to hold data, they will be initialized later.
            var plainTextBlob = DPAPINativeDataBlob.Null();
            var cipherTextBlob = DPAPINativeDataBlob.Null();
            var entropyBlob = DPAPINativeDataBlob.Null();

            // We only need prompt structure because it is a required parameter.
            var prompt = DPAPINativeCryptPotectPromptStruct.Default();

            byte[] cipherTextBytes;

            try
            {
                // Convert plaintext bytes into a BLOB structure.
                plainTextBlob = DPAPINativeDataBlob.Init(plainTextBytes); // InitBLOB(plainTextBytes);

                // Convert entropy bytes into a BLOB structure.
                entropyBlob = DPAPINativeDataBlob.Init(entropyBytes); // InitBLOB(entropyBytes);

                // Disable any types of UI.
                var flags = CRYPTPROTECT_UI_FORBIDDEN;

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

                // Call DPAPI to encrypt data.
                var success = CryptProtectData(ref plainTextBlob, string.Empty, ref entropyBlob, IntPtr.Zero, ref prompt, flags, ref cipherTextBlob);

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

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

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

                // Copy ciphertext from the BLOB to a byte array.
                Marshal.Copy(cipherTextBlob.DataPointer, cipherTextBytes, 0, cipherTextBlob.DataLength);
            }
            catch (Exception ex)
            {
                throw new CryptographicException("DPAPI was unable to encrypt data.", ex);
            }
            finally
            {
                // Free all memory allocated for BLOBs.
                plainTextBlob.Dispose();
                cipherTextBlob.Dispose();
                entropyBlob.Dispose();

                prompt.Dispose();
            }

            // Return the result.
            return cipherTextBytes;
        }
        public void SetEncoding(DPAPIKeyType keyType, Encodings encodingType)
        {
            Encoding encoding = null;

            switch (encodingType)
            {
                    //case Encodings.None:
                case Encodings.ASCII :
                    encoding = Encoding.ASCII;
                    break;
                case Encodings.UTF7 :
                    encoding = Encoding.UTF7;
                    break;
                case Encodings.UTF8 :
                    encoding = Encoding.UTF8;
                    break;
            }

            var engine = new DPAPIEngine(keyType)
                .SetEncoding(encoding);

            byte[] plainText = encoding.GetBytes(GenerateClearText());

            byte[] encrypted = engine.Encrypt(plainText);

            byte[] decrypted = engine.Decrypt(encrypted);

            Assert.NotEqual(plainText, encrypted);
            Assert.NotEqual(encrypted, decrypted);
            Assert.Equal(plainText, decrypted);
        }
        public void Failures(DPAPIKeyType keyType)
        {
            string plainText = GenerateClearText();

            var engine = new DPAPIEngine(keyType);

            string badEncrypt = Convert.ToBase64String(Encoding.UTF8.GetBytes(plainText));

            Assert.Throws<CryptographicException>(() =>
            {
                engine.Decrypt(badEncrypt);
            });
        }