Exemple #1
0
 private static void DecryptFile(string filePath, int parametersLength, byte[] macBackup, byte[] encryptionKey)
 {
     try
     {
         string decryptedFilePath = Regex.Replace(filePath, Constants.EncryptedExtension, string.Empty);
         int    headersLength     = Constants.SaltLength + parametersLength;
         using (var plaintext = new FileStream(decryptedFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, Constants.FileBufferSize, FileOptions.SequentialScan))
             using (var ciphertext = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, Constants.FileBufferSize, FileOptions.SequentialScan))
             {
                 // Skip the header bytes
                 ciphertext.Seek(headersLength, SeekOrigin.Begin);
                 byte[] fileBytes = FileHandling.GetBufferSize(ciphertext.Length);
                 // Generate a counter starting at 0
                 byte[] counter = Generate.Counter();
                 int    bytesRead;
                 MemoryEncryption.DecryptByteArray(ref encryptionKey);
                 while ((bytesRead = ciphertext.Read(fileBytes, 0, fileBytes.Length)) > 0)
                 {
                     byte[] decryptedBytes = StreamEncryption.DecryptXChaCha20(fileBytes, counter, encryptionKey);
                     plaintext.Write(decryptedBytes, 0, bytesRead);
                     counter = Sodium.Utilities.Increment(counter);
                 }
                 Utilities.ZeroArray(encryptionKey);
             }
         CompleteDecryption(filePath, decryptedFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.FileEncryptionExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to decrypt the file.");
         Utilities.ZeroArray(encryptionKey);
         RestoreMAC(filePath, macBackup);
     }
 }
Exemple #2
0
 private static void UsingPassword(string inputFilePath, byte[] passwordBytes)
 {
     try
     {
         bool fileIsDirectory = FileHandling.IsDirectory(inputFilePath);
         if (fileIsDirectory)
         {
             DirectoryDecryption.UsingPassword(inputFilePath, passwordBytes);
             return;
         }
         byte[] salt             = FileHeaders.ReadSalt(inputFilePath);
         byte[] keyEncryptionKey = Argon2.DeriveKey(passwordBytes, salt);
         string outputFilePath   = GetOutputFilePath(inputFilePath);
         DecryptFile.Initialize(inputFilePath, outputFilePath, keyEncryptionKey);
         Utilities.ZeroArray(keyEncryptionKey);
         DecryptionSuccessful(inputFilePath, outputFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccess(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Error);
         if (ex is ArgumentException || ex is ArgumentOutOfRangeException)
         {
             DisplayMessage.FilePathMessage(inputFilePath, ex.Message);
             return;
         }
         DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to decrypt the file.");
     }
 }
Exemple #3
0
 private static void EncryptFile(string filePath, string encryptedFilePath, byte[] salt, byte[] encryptionKey, byte[] macKey)
 {
     try
     {
         using (var ciphertext = new FileStream(encryptedFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, Constants.FileBufferSize, FileOptions.SequentialScan))
             using (var plaintext = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, Constants.FileBufferSize, FileOptions.SequentialScan))
             {
                 WriteFileHeaders.WriteHeaders(ciphertext, salt);
                 byte[] fileBytes = FileHandling.GetBufferSize(plaintext.Length);
                 // Generate a counter starting at 0
                 byte[] counter = Generate.Counter();
                 int    bytesRead;
                 MemoryEncryption.DecryptByteArray(ref encryptionKey);
                 while ((bytesRead = plaintext.Read(fileBytes, 0, fileBytes.Length)) > 0)
                 {
                     byte[] encryptedBytes = StreamEncryption.EncryptXChaCha20(fileBytes, counter, encryptionKey);
                     ciphertext.Write(encryptedBytes, 0, bytesRead);
                     counter = Sodium.Utilities.Increment(counter);
                 }
             }
         Utilities.ZeroArray(encryptionKey);
         CompleteEncryption(filePath, encryptedFilePath, macKey);
     }
     catch (Exception ex) when(ExceptionFilters.FileEncryptionExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to encrypt the file.");
         FileHandling.DeleteFile(encryptedFilePath);
         Utilities.ZeroArray(encryptionKey);
         Utilities.ZeroArray(macKey);
     }
 }
Exemple #4
0
 private static void UsingPassword(string inputFilePath, byte[] passwordBytes)
 {
     try
     {
         bool fileIsDirectory = FileHandling.IsDirectory(inputFilePath);
         if (fileIsDirectory)
         {
             DirectoryEncryption.UsingPassword(inputFilePath, passwordBytes);
             return;
         }
         // Derive a unique KEK per file
         byte[] salt             = Generate.Salt();
         byte[] keyEncryptionKey = Argon2.DeriveKey(passwordBytes, salt);
         // Fill the ephemeral public key header with random key (since not in use)
         byte[] randomEphemeralPublicKeyHeader = Generate.EphemeralPublicKeyHeader();
         string outputFilePath = GetOutputFilePath(inputFilePath);
         EncryptFile.Initialize(inputFilePath, outputFilePath, randomEphemeralPublicKeyHeader, salt, keyEncryptionKey);
         Utilities.ZeroArray(keyEncryptionKey);
         EncryptionSuccessful(inputFilePath, outputFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccess(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Error);
         DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to encrypt the file.");
     }
 }
Exemple #5
0
 public static void Initialize(string inputFilePath, string outputFilePath, byte[] keyEncryptionKey)
 {
     byte[] dataEncryptionKey = new byte[Constants.EncryptionKeyLength];
     try
     {
         byte[] encryptedHeader = FileHeaders.ReadEncryptedHeader(inputFilePath);
         byte[] nonce           = FileHeaders.ReadNonce(inputFilePath);
         byte[] header          = DecryptFileHeader(inputFilePath, encryptedHeader, nonce, keyEncryptionKey);
         if (header == null)
         {
             throw new ArgumentException("Incorrect password/keyfile or this file has been tampered with.");
         }
         ChunkHandling.ValidateKeyCommitmentBlock(header);
         int lastChunkLength = FileHeaders.GetLastChunkLength(header);
         int fileNameLength  = FileHeaders.GetFileNameLength(header);
         dataEncryptionKey = FileHeaders.GetDataEncryptionKey(header);
         Utilities.ZeroArray(header);
         using (var inputFile = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan))
             using (var outputFile = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan))
             {
                 nonce = Sodium.Utilities.Increment(nonce);
                 byte[] additionalData = ChunkHandling.GetPreviousPoly1305Tag(encryptedHeader);
                 Decrypt(inputFile, outputFile, nonce, dataEncryptionKey, additionalData, lastChunkLength);
             }
         Finalize(inputFilePath, outputFilePath, fileNameLength);
     }
     catch (Exception ex) when(ExceptionFilters.Cryptography(ex))
     {
         Utilities.ZeroArray(dataEncryptionKey);
         throw;
     }
 }
Exemple #6
0
 public static void SignEachFile(byte[] privateKey, string comment, bool preHash, string[] filePaths)
 {
     privateKey = PrivateKey.Decrypt(privateKey);
     if (privateKey == null)
     {
         return;
     }
     if (string.IsNullOrEmpty(comment))
     {
         comment = _defaultComment;
     }
     foreach (string filePath in filePaths)
     {
         try
         {
             DigitalSignatures.SignFile(filePath, comment, preHash, privateKey);
             DisplayMessage.FilePathMessage(filePath, "File signed successfully.");
         }
         catch (Exception ex) when(ExceptionFilters.Cryptography(ex))
         {
             Logging.LogException(ex.ToString(), Logging.Severity.Error);
             DisplayMessage.FilePathException(filePath, ex.GetType().Name, "Unable to create signature.");
         }
     }
     Utilities.ZeroArray(privateKey);
 }
Exemple #7
0
 public static char[] ConvertUserInput(bool encryption, char[] base64Key, char[] password)
 {
     try
     {
         NullChecks.CharArray(base64Key);
         NullChecks.CharArray(password);
         char[] message;
         byte[] key = Convert.FromBase64CharArray(base64Key, 0, base64Key.Length);
         if (encryption == true)
         {
             byte[] plaintext = Encoding.UTF8.GetBytes(password);
             message = EncryptPassword(plaintext, key);
             Utilities.ZeroArray(plaintext);
         }
         else
         {
             byte[] ciphertext = Convert.FromBase64CharArray(password, 0, password.Length);
             message = DecryptPassword(ciphertext, key);
             Utilities.ZeroArray(ciphertext);
         }
         Utilities.ZeroArray(key);
         return(message);
     }
     catch (Exception ex) when(ex is FormatException || ex is EncoderFallbackException)
     {
         DisplayMessage.Error(ex.GetType().Name, "Invalid key or password format.");
         return(Array.Empty <char>());
     }
 }
Exemple #8
0
 private static void UsingPublicKey(string inputFilePath, byte[] sharedSecret, byte[] recipientPublicKey)
 {
     try
     {
         bool fileIsDirectory = FileHandling.IsDirectory(inputFilePath);
         if (fileIsDirectory)
         {
             DirectoryEncryption.UsingPublicKey(inputFilePath, sharedSecret, recipientPublicKey);
             return;
         }
         // Derive a unique KEK per file
         (byte[] ephemeralSharedSecret, byte[] ephemeralPublicKey) = KeyExchange.GetEphemeralSharedSecret(recipientPublicKey);
         byte[] salt             = Generate.Salt();
         byte[] keyEncryptionKey = Generate.KeyEncryptionKey(sharedSecret, ephemeralSharedSecret, salt);
         string outputFilePath   = GetOutputFilePath(inputFilePath);
         EncryptFile.Initialize(inputFilePath, outputFilePath, ephemeralPublicKey, salt, keyEncryptionKey);
         Utilities.ZeroArray(keyEncryptionKey);
         EncryptionSuccessful(inputFilePath, outputFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccess(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Error);
         DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to encrypt the file.");
     }
 }
Exemple #9
0
 public static void GenerateKeyfile(string keyfilePath)
 {
     byte[] keyfileBytes = Generate.Keyfile();
     File.WriteAllBytes(keyfilePath, keyfileBytes);
     File.SetAttributes(keyfilePath, FileAttributes.ReadOnly);
     Utilities.ZeroArray(keyfileBytes);
 }
Exemple #10
0
        public static void RecoverPublicKey(string privateKeyPath)
        {
            bool validUserInput = FilePathValidation.RecoverPublicKey(privateKeyPath);

            if (!validUserInput)
            {
                return;
            }
            byte[] privateKey = AsymmetricKeyValidation.GetPrivateKeyFromFile(privateKeyPath);
            if (privateKey == null)
            {
                return;
            }
            privateKey = PrivateKey.Decrypt(privateKey);
            if (privateKey == null)
            {
                return;
            }
            byte[] publicKey = privateKey.Length switch
            {
                Constants.EncryptionKeyLength => AsymmetricKeys.GetCurve25519PublicKey(privateKey),
                _ => AsymmetricKeys.GetEd25519PublicKey(privateKey),
            };
            Utilities.ZeroArray(privateKey);
            Console.WriteLine($"Public key: {Convert.ToBase64String(publicKey)}");
        }
Exemple #11
0
 private static void UsingPrivateKey(string inputFilePath, byte[] sharedSecret, byte[] recipientPrivateKey)
 {
     try
     {
         bool fileIsDirectory = FileHandling.IsDirectory(inputFilePath);
         if (fileIsDirectory)
         {
             DirectoryDecryption.UsingPrivateKey(inputFilePath, sharedSecret, recipientPrivateKey);
             return;
         }
         byte[] ephemeralPublicKey    = FileHeaders.ReadEphemeralPublicKey(inputFilePath);
         byte[] ephemeralSharedSecret = KeyExchange.GetSharedSecret(recipientPrivateKey, ephemeralPublicKey);
         byte[] salt             = FileHeaders.ReadSalt(inputFilePath);
         byte[] keyEncryptionKey = Generate.KeyEncryptionKey(sharedSecret, ephemeralSharedSecret, salt);
         string outputFilePath   = GetOutputFilePath(inputFilePath);
         DecryptFile.Initialize(inputFilePath, outputFilePath, keyEncryptionKey);
         Utilities.ZeroArray(keyEncryptionKey);
         DecryptionSuccessful(inputFilePath, outputFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccess(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Error);
         if (ex is ArgumentException || ex is ArgumentOutOfRangeException)
         {
             DisplayMessage.FilePathMessage(inputFilePath, ex.Message);
             return;
         }
         DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to decrypt the file.");
     }
 }
Exemple #12
0
 public static void CallEncryption(bool encryption, char[] password, string keyfilePath, string[] filePaths)
 {
     byte[] passwordBytes = FileEncryption.GetPasswordBytes(password);
     Utilities.ZeroArray(password);
     FileEncryption.StartEncryption(encryption, filePaths, passwordBytes, keyfilePath);
     EncryptionCompleted(encryption);
 }
Exemple #13
0
 public static byte[] KeyEncryptionKey(byte[] sharedSecret, byte[] ephemeralSharedSecret, byte[] salt)
 {
     byte[] inputKeyingMaterial = Utilities.ConcatArrays(sharedSecret, ephemeralSharedSecret);
     byte[] keyEncryptionKey    = Blake2.KeyDerivation(inputKeyingMaterial, salt, Constants.EncryptionKeyLength);
     Utilities.ZeroArray(ephemeralSharedSecret);
     Utilities.ZeroArray(inputKeyingMaterial);
     return(keyEncryptionKey);
 }
Exemple #14
0
        private static void CompleteEncryption(string filePath, string encryptedFilePath, byte[] macKey)
        {
            // Calculate and append MAC
            bool fileSigned = FileAuthentication.SignFile(encryptedFilePath, macKey);

            Utilities.ZeroArray(macKey);
            if (fileSigned == true && Globals.OverwriteFiles == true)
            {
                FileHandling.OverwriteFile(filePath, encryptedFilePath);
            }
            FileHandling.MakeFileReadOnly(encryptedFilePath);
            GetEncryptionResult(filePath, fileSigned);
        }
Exemple #15
0
 public static void GenerateRandomPassword(int length)
 {
     if (length >= 8 && length <= 128)
     {
         char[] password = PasswordGenerator.GenerateRandomPassword(length, true, true, true, true);
         Console.WriteLine(password);
         Utilities.ZeroArray(password);
     }
     else
     {
         Console.WriteLine("Error: Invalid length. Randomly generated passwords must be between 8-128 characters.");
     }
 }
Exemple #16
0
 public static void GenerateRandomPassphrase(int length)
 {
     if (length >= 4 && length <= 20)
     {
         char[] passphrase = PasswordGenerator.GenerateRandomPassphrase(length, true, true);
         Console.WriteLine(passphrase);
         Utilities.ZeroArray(passphrase);
     }
     else
     {
         Console.WriteLine("Error: Invalid number of words. Randomly generated passphrases must be between 4-20 words.");
     }
 }
Exemple #17
0
 public static byte[] Encrypt(byte[] passwordBytes, byte[] privateKey, byte[] keyAlgorithm)
 {
     byte[] salt = Generate.Salt();
     byte[] key  = Argon2.DeriveKey(passwordBytes, salt);
     Utilities.ZeroArray(passwordBytes);
     byte[] nonce              = Generate.Nonce();
     byte[] additionalData     = Utilities.ConcatArrays(keyAlgorithm, Constants.PrivateKeyVersion);
     byte[] keyCommitmentBlock = ChunkHandling.GetKeyCommitmentBlock();
     privateKey = Utilities.ConcatArrays(keyCommitmentBlock, privateKey);
     byte[] encryptedPrivateKey = SecretAeadXChaCha20Poly1305.Encrypt(privateKey, nonce, key, additionalData);
     Utilities.ZeroArray(privateKey);
     Utilities.ZeroArray(key);
     return(Utilities.ConcatArrays(additionalData, salt, nonce, encryptedPrivateKey));
 }
Exemple #18
0
 public static void StartEncryption(bool encryption, string[] filePaths, byte[] passwordBytes, string keyfilePath)
 {
     // Don't use keyfile bytes when only a keyfile is selected
     if (passwordBytes != null)
     {
         passwordBytes = GetKeyfileBytes(passwordBytes, keyfilePath);
     }
     else
     {
         passwordBytes = KeyfileAsPassword(keyfilePath);
     }
     GetFilePaths(encryption, filePaths, passwordBytes);
     Utilities.ZeroArray(passwordBytes);
 }
 private static void DecryptEachFileWithPassword(string[] filePaths, byte[] keyEncryptionKey)
 {
     foreach (string inputFilePath in filePaths)
     {
         bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
         if (!validFilePath)
         {
             --Globals.TotalCount;
             continue;
         }
         DecryptInputFile(inputFilePath, keyEncryptionKey);
     }
     Utilities.ZeroArray(keyEncryptionKey);
 }
Exemple #20
0
        private static void Encrypt(FileStream inputFile, FileStream outputFile, byte[] nonce, byte[] dataEncryptionKey, byte[] additionalData)
        {
            const int offset = 0;

            byte[] plaintext = new byte[Constants.FileChunkSize];
            while (inputFile.Read(plaintext, offset, plaintext.Length) > 0)
            {
                byte[] plaintextChunk  = ChunkHandling.PrependKeyCommitmentBlock(plaintext);
                byte[] ciphertextChunk = SecretAeadXChaCha20Poly1305.Encrypt(plaintextChunk, nonce, dataEncryptionKey, additionalData);
                nonce          = Sodium.Utilities.Increment(nonce);
                additionalData = ChunkHandling.GetPreviousPoly1305Tag(ciphertextChunk);
                outputFile.Write(ciphertextChunk, offset, ciphertextChunk.Length);
            }
            Utilities.ZeroArray(dataEncryptionKey);
        }
Exemple #21
0
        private static void CheckForTampering(string filePath, int parametersLength, byte[] encryptionKey, byte[] macKey)
        {
            bool fileTampered = FileAuthentication.AuthenticateFile(filePath, macKey, out byte[] macBackup);

            Utilities.ZeroArray(macKey);
            if (fileTampered == false)
            {
                DecryptFile(filePath, parametersLength, macBackup, encryptionKey);
            }
            else
            {
                Console.WriteLine($"{Path.GetFileName(filePath)}: Incorrect password/keyfile, wrong encryption algorithm, or this file has been tampered with.");
                Utilities.ZeroArray(encryptionKey);
            }
        }
Exemple #22
0
 private static byte[] Decrypt(byte[] passwordBytes, byte[] privateKey)
 {
     byte[] keyAlgorithm        = GetKeyAlgorithm(privateKey);
     byte[] keyVersion          = GetKeyVersion(privateKey);
     byte[] salt                = GetSalt(privateKey);
     byte[] nonce               = GetNonce(privateKey);
     byte[] additionalData      = Utilities.ConcatArrays(keyAlgorithm, keyVersion);
     byte[] encryptedPrivateKey = GetEncryptedPrivateKey(privateKey);
     byte[] key = Argon2.DeriveKey(passwordBytes, salt);
     Utilities.ZeroArray(passwordBytes);
     byte[] decryptedPrivateKey = SecretAeadXChaCha20Poly1305.Decrypt(encryptedPrivateKey, nonce, key, additionalData);
     Utilities.ZeroArray(key);
     ChunkHandling.ValidateKeyCommitmentBlock(decryptedPrivateKey);
     return(ChunkHandling.RemoveKeyCommitmentBlock(decryptedPrivateKey));
 }
Exemple #23
0
 public static void GenerateKeyfile(string filePath)
 {
     try
     {
         byte[] keyfileBytes = SodiumCore.GetRandomBytes(Constants.MACKeySize);
         File.WriteAllBytes(filePath, keyfileBytes);
         File.SetAttributes(filePath, FileAttributes.ReadOnly);
         Utilities.ZeroArray(keyfileBytes);
         Console.WriteLine("Keyfile successfully generated.");
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Low);
         DisplayMessage.Error(ex.GetType().Name, "Keyfile generation failed.");
     }
 }
Exemple #24
0
 public static void EncryptEachFileWithPassword(string[] filePaths, byte[] passwordBytes)
 {
     Globals.TotalCount = filePaths.Length;
     foreach (string inputFilePath in filePaths)
     {
         bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
         if (!validFilePath)
         {
             --Globals.TotalCount;
             continue;
         }
         UsingPassword(inputFilePath, passwordBytes);
     }
     Utilities.ZeroArray(passwordBytes);
     DisplayMessage.SuccessfullyEncrypted();
 }
Exemple #25
0
 private static byte[] GetKeyfileBytes(byte[] passwordBytes, string keyfilePath)
 {
     if (!string.IsNullOrEmpty(keyfilePath))
     {
         byte[] keyfileBytes = Keyfiles.ReadKeyfile(keyfilePath);
         if (keyfileBytes != null)
         {
             MemoryEncryption.DecryptByteArray(ref passwordBytes);
             // Combine password and keyfile bytes
             passwordBytes = HashingAlgorithms.Blake2(passwordBytes, keyfileBytes);
             MemoryEncryption.EncryptByteArray(ref passwordBytes);
             Utilities.ZeroArray(keyfileBytes);
         }
     }
     return(passwordBytes);
 }
 private static void EncryptEachFileWithPassword(string[] filePaths, byte[] salt, byte[] keyEncryptionKey)
 {
     foreach (string inputFilePath in filePaths)
     {
         bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
         if (!validFilePath)
         {
             --Globals.TotalCount;
             continue;
         }
         // Fill the ephemeral public key header with random bytes (since not in use)
         byte[] randomEphemeralPublicKeyHeader = Generate.EphemeralPublicKeyHeader();
         string outputFilePath = FileEncryption.GetOutputFilePath(inputFilePath);
         EncryptInputFile(inputFilePath, outputFilePath, randomEphemeralPublicKeyHeader, salt, keyEncryptionKey);
     }
     Utilities.ZeroArray(keyEncryptionKey);
 }
 private static void DecryptEachFileWithPrivateKey(string[] filePaths, byte[] privateKey)
 {
     foreach (string inputFilePath in filePaths)
     {
         bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
         if (!validFilePath)
         {
             --Globals.TotalCount;
             continue;
         }
         byte[] ephemeralPublicKey    = FileHeaders.ReadEphemeralPublicKey(inputFilePath);
         byte[] ephemeralSharedSecret = KeyExchange.GetSharedSecret(privateKey, ephemeralPublicKey);
         byte[] salt             = FileHeaders.ReadSalt(inputFilePath);
         byte[] keyEncryptionKey = Generate.KeyEncryptionKey(ephemeralSharedSecret, salt);
         DecryptInputFile(inputFilePath, keyEncryptionKey);
         Utilities.ZeroArray(keyEncryptionKey);
     }
 }
Exemple #28
0
        private static void RestoreMAC(string filePath, byte[] macBackup)
        {
            bool restored = FileAuthentication.AppendHash(filePath, macBackup);

            if (restored == false)
            {
                try
                {
                    File.WriteAllBytes($"{filePath}.backup", macBackup);
                }
                catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
                {
                    Logging.LogException(ex.ToString(), Logging.Severity.High);
                    DisplayMessage.Error(filePath, ex.GetType().Name, "Failed to backup the MAC. This data is required for decryption.");
                }
            }
            Utilities.ZeroArray(macBackup);
        }
 private static void EncryptEachFileWithPrivateKey(string[] filePaths, byte[] privateKey)
 {
     foreach (string inputFilePath in filePaths)
     {
         bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
         if (!validFilePath)
         {
             --Globals.TotalCount;
             continue;
         }
         // Derive a unique KEK per file
         (byte[] ephemeralSharedSecret, byte[] ephemeralPublicKey) = KeyExchange.GetPrivateKeySharedSecret(privateKey);
         byte[] salt             = Generate.Salt();
         byte[] keyEncryptionKey = Generate.KeyEncryptionKey(ephemeralSharedSecret, salt);
         string outputFilePath   = FileEncryption.GetOutputFilePath(inputFilePath);
         EncryptInputFile(inputFilePath, outputFilePath, ephemeralPublicKey, salt, keyEncryptionKey);
         Utilities.ZeroArray(keyEncryptionKey);
     }
 }
Exemple #30
0
        public static (byte[] encryptionKey, byte[] macKey) DeriveKeys(byte[] passwordBytes, byte[] salt, int iterations, int memorySize)
        {
            var argon2id = PasswordHash.ArgonAlgorithm.Argon_2ID13;

            MemoryEncryption.DecryptByteArray(ref passwordBytes);
            // Derive a 96 byte key
            byte[] derivedKey = PasswordHash.ArgonHashBinary(passwordBytes, salt, iterations, memorySize, Constants.Argon2KeySize, argon2id);
            // 256-bit encryption key
            byte[] encryptionKey = new byte[Constants.EncryptionKeySize];
            Array.Copy(derivedKey, encryptionKey, encryptionKey.Length);
            // 512-bit MAC key
            byte[] macKey = new byte[Constants.MACKeySize];
            Array.Copy(derivedKey, encryptionKey.Length, macKey, 0, macKey.Length);
            Utilities.ZeroArray(derivedKey);
            MemoryEncryption.EncryptByteArray(ref passwordBytes);
            MemoryEncryption.EncryptByteArray(ref encryptionKey);
            MemoryEncryption.EncryptByteArray(ref macKey);
            return(encryptionKey, macKey);
        }