Ejemplo n.º 1
0
        public static async Task <string> Decrypt(string cipherText, string password, string salt = "Kosher",
                                                  string hashAlgorithm   = "SHA1",
                                                  int passwordIterations = 2,
                                                  int keySize            = 256)
        {
            return(await Task.Run(() =>
            {
                if (string.IsNullOrEmpty(cipherText))
                {
                    return null;
                }
                if (string.IsNullOrEmpty(password))
                {
                    return null;
                }

                byte[] initialVectorBytes;
                byte[] saltValueBytes;
                byte[] cipherTextBytes = Convert.FromBase64String(cipherText);

                // Extract metadata from file
                AESMetadata metadata = new AESMetadata();
                if (!metadata.GetMetadata(cipherTextBytes))
                {
                    // Metadata parsing error
                    DialogResult result = MessageBox.Show("Unable to parse file metadata.\nAttempt to open anyway?\n(May result in a \'Incorrect Key\' error if the salt is wrong.)",
                                                          "Missing or Corrupted Metadata", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                    if (result == DialogResult.Yes)
                    {
                        // Default initialization vector from builds v1.1.2 and older
                        const string default_IV = "16CHARSLONG12345";
                        initialVectorBytes = Encoding.ASCII.GetBytes(default_IV);
                        saltValueBytes = Encoding.ASCII.GetBytes(salt);
                    }
                    else
                    {
                        PublicVar.metadataCorrupt = true;
                        return null;
                    }
                }
                else
                {
                    saltValueBytes = metadata.Salt;
                    initialVectorBytes = metadata.InitialVector;
                    metadata.DeleteMetadataFromBuffer(ref cipherTextBytes);
                }

                PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes
                                                          (password, saltValueBytes, hashAlgorithm, passwordIterations);
                byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);

                RijndaelManaged symmetricKey = new RijndaelManaged();
                symmetricKey.Mode = CipherMode.CBC;

                byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                int byteCount = 0;

                using (MemoryStream memStream = new MemoryStream(cipherTextBytes))
                {
                    using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor
                                                            (keyBytes, initialVectorBytes))
                    {
                        using (CryptoStream cryptoStream
                                   = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                        {
                            byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                            memStream.Close();
                            cryptoStream.Close();
                        }
                    }

                    symmetricKey.Dispose();
                }

                derivedPassword.Dispose();

                return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
            }));
        }
Ejemplo n.º 2
0
        public static async Task <string> Encrypt(string plainText, string password,
                                                  string salt            = null, string hashAlgorithm = "SHA1",
                                                  int passwordIterations = 2, int keySize             = 256)
        {
            return(await Task.Run(() =>
            {
                if (string.IsNullOrEmpty(plainText))
                {
                    return null;
                }
                if (string.IsNullOrEmpty(password))
                {
                    return null;
                }

                byte[] plainTextBytes;
                byte[] saltValueBytes;

                // In case user wants a random salt or salt is null/empty for some other reason
                if (string.IsNullOrEmpty(salt))
                {
                    saltValueBytes = new byte[64];  // Nice and long
                    saltValueBytes = GenerateSecureNonZeroByteArray(saltValueBytes.Length);
                }
                else
                {
                    saltValueBytes = Encoding.ASCII.GetBytes(salt);
                }

                plainTextBytes = Encoding.UTF8.GetBytes(plainText);

                PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes
                                                          (password, saltValueBytes, hashAlgorithm, passwordIterations);

                // Null password; adds *some* memory dump protection
                password = null;

                byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
                RijndaelManaged symmetricKey = new RijndaelManaged();
                symmetricKey.Mode = CipherMode.CBC;

                // Generate IV
                symmetricKey.IV = GenerateSecureNonZeroByteArray(symmetricKey.IV.Length);

                byte[] cipherTextBytes = null;

                using (MemoryStream memStream = new MemoryStream())
                {
                    AESMetadata.WriteMetadata(memStream, symmetricKey.IV, saltValueBytes);

                    using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor
                                                            (keyBytes, symmetricKey.IV))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream
                                                               (memStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            cipherTextBytes = memStream.ToArray();
                            memStream.Close();
                            cryptoStream.Close();
                        }
                    }
                }

                symmetricKey.Dispose();
                derivedPassword.Dispose();
                return Convert.ToBase64String(cipherTextBytes);
            }));
        }