Exemple #1
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);
     }
 }
        private static void CreateSaltFile(string directoryPath, byte[] salt)
        {
            string saltFilePath = Path.Combine(directoryPath, Constants.SaltFile);

            File.WriteAllBytes(saltFilePath, salt);
            FileHandling.SetFileAttributesReadOnly(saltFilePath);
        }
Exemple #3
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.");
     }
 }
 private static void UsingPublicKey(string inputFilePath, byte[] sharedSecret, byte[] recipientPrivateKey)
 {
     try
     {
         bool fileIsDirectory = FileHandling.IsDirectory(inputFilePath);
         if (fileIsDirectory)
         {
             DirectoryDecryption.UsingPublicKey(inputFilePath, sharedSecret, recipientPrivateKey);
             return;
         }
         using var inputFile = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess);
         byte[] ephemeralPublicKey    = FileHeaders.ReadEphemeralPublicKey(inputFile);
         byte[] ephemeralSharedSecret = KeyExchange.GetSharedSecret(recipientPrivateKey, ephemeralPublicKey);
         byte[] salt             = FileHeaders.ReadSalt(inputFile);
         byte[] keyEncryptionKey = Generate.KeyEncryptionKey(sharedSecret, ephemeralSharedSecret, salt);
         string outputFilePath   = GetOutputFilePath(inputFilePath);
         DecryptFile.Initialize(inputFile, outputFilePath, ephemeralPublicKey, keyEncryptionKey);
         CryptographicOperations.ZeroMemory(keyEncryptionKey);
         DecryptionSuccessful(inputFilePath, outputFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.Cryptography(ex))
     {
         FileException(inputFilePath, ex);
     }
 }
Exemple #5
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 #6
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 #7
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 #8
0
        private static byte[] GetCommentBytes(FileStream signatureFile)
        {
            int offset = Constants.SignatureMagicBytes.Length + Constants.SignatureVersion.Length + _preHashedHeaderLength + Constants.SignatureLength;
            int length = (int)(signatureFile.Length - offset - Constants.SignatureLength);

            return(FileHandling.ReadFileHeader(signatureFile, length));
        }
 private static void RestoreDirectoryName(string obfuscatedDirectoryPath)
 {
     try
     {
         string obfuscatedDirectoryName = Path.GetFileName(obfuscatedDirectoryPath);
         // Get the path where the original directory name is stored
         string storageFileName = $"{obfuscatedDirectoryName}.txt";
         string storageFilePath = Path.Combine(obfuscatedDirectoryPath, storageFileName);
         if (!File.Exists(storageFilePath))
         {
             return;
         }
         string directoryName = File.ReadAllText(storageFilePath);
         string directoryPath = obfuscatedDirectoryPath.Replace(obfuscatedDirectoryName, directoryName);
         directoryPath = FileHandling.GetUniqueDirectoryPath(directoryPath);
         Directory.Move(obfuscatedDirectoryPath, directoryPath);
         DisplayMessage.FileEncryptionResult(obfuscatedDirectoryName, directoryName);
         storageFilePath = Path.Combine(directoryPath, storageFileName);
         FileHandling.DeleteFile(storageFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccess(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Error);
         DisplayMessage.FilePathException(obfuscatedDirectoryPath, ex.GetType().Name, "Unable to restore the directory name.");
     }
 }
 private static string[] GetFiles(string directoryPath)
 {
     string[] filePaths = FileHandling.GetAllFiles(directoryPath);
     // -1 for the selected directory
     Globals.TotalCount += filePaths.Length - 1;
     return(filePaths);
 }
 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 unused header with random public key
         byte[] ephemeralPublicKey = Generate.EphemeralPublicKeyHeader();
         string outputFilePath     = GetOutputFilePath(inputFilePath);
         EncryptFile.Initialize(inputFilePath, outputFilePath, ephemeralPublicKey, salt, keyEncryptionKey);
         CryptographicOperations.ZeroMemory(keyEncryptionKey);
         EncryptionSuccessful(inputFilePath, outputFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.Cryptography(ex))
     {
         DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to encrypt the file.");
     }
 }
Exemple #12
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 #13
0
        private static bool IsPreHashingRequired(string filePath)
        {
            int  oneGibibyte = 1024 * Constants.Mebibyte;
            long fileSize    = FileHandling.GetFileLength(filePath);

            return(fileSize >= oneGibibyte);
        }
 private static void Finalize(string directoryPath, string saltFilePath)
 {
     if (Globals.SuccessfulCount != 0 && Globals.SuccessfulCount == Globals.TotalCount)
     {
         FileHandling.DeleteFile(saltFilePath);
     }
     Finalize(directoryPath);
 }
Exemple #15
0
 private static void CompleteDecryption(string filePath, string decryptedFilePath)
 {
     // Deanonymise file name
     OriginalFileName.RestoreOriginalFileName(decryptedFilePath);
     FileHandling.DeleteFile(filePath);
     Console.WriteLine($"{Path.GetFileName(filePath)}: File decryption successful.");
     Globals.SuccessfulCount += 1;
 }
 private static void Finalize(string directoryPath, string saltFilePath)
 {
     string[] kryptorFiles = Directory.GetFiles(directoryPath, $"*{Constants.EncryptedExtension}", SearchOption.AllDirectories);
     if (kryptorFiles.Length == 0)
     {
         FileHandling.DeleteFile(saltFilePath);
     }
     Finalize(directoryPath);
 }
        public static void AppendFileName(string filePath)
        {
            Encoding fileEncoding = FileHandling.GetFileEncoding(filePath);
            string   fileName     = Path.GetFileName(filePath);

            byte[] fileNameBytes = fileEncoding.GetBytes(fileName);
            using var fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess);
            fileStream.Write(fileNameBytes, offset: 0, fileNameBytes.Length);
        }
 public static void AllDirectories(string directoryPath)
 {
     string[] subdirectories = FileHandling.GetAllDirectories(directoryPath);
     // Deobfuscate subdirectory names - bottom most first
     for (int i = subdirectories.Length - 1; i >= 0; i--)
     {
         RestoreDirectoryName(subdirectories[i]);
     }
     RestoreDirectoryName(directoryPath);
 }
Exemple #19
0
        private static byte[] EncryptFileHeader(string inputFilePath, byte[] ephemeralPublicKey, byte[] dataEncryptionKey, byte[] nonce, byte[] keyEncryptionKey)
        {
            long fileLength = FileHandling.GetFileLength(inputFilePath);

            byte[] lastChunkLength = BitConversion.GetBytes(Convert.ToInt32(fileLength % Constants.FileChunkSize));
            byte[] fileNameLength  = FileHeaders.GetFileNameLength(inputFilePath);
            byte[] fileHeader      = Arrays.Concat(lastChunkLength, fileNameLength, dataEncryptionKey);
            byte[] additionalData  = HeaderEncryption.ComputeAdditionalData(fileLength, ephemeralPublicKey);
            return(HeaderEncryption.Encrypt(fileHeader, nonce, keyEncryptionKey, additionalData));
        }
 public static string AllDirectories(string directoryPath)
 {
     string[] subdirectories = FileHandling.GetAllDirectories(directoryPath);
     // Obfuscate subdirectory names - bottom most first
     for (int i = subdirectories.Length - 1; i >= 0; i--)
     {
         ObfuscateDirectoryName(subdirectories[i]);
     }
     // Obfuscate parent directory name
     return(ObfuscateDirectoryName(directoryPath));
 }
Exemple #21
0
        private static byte[] EncryptFileHeader(string inputFilePath, byte[] dataEncryptionKey, byte[] nonce, byte[] keyEncryptionKey)
        {
            byte[] keyCommitmentBlock = ChunkHandling.GetKeyCommitmentBlock();
            long   fileLength         = FileHandling.GetFileLength(inputFilePath);

            byte[] lastChunkLength = BitConverter.GetBytes(Convert.ToInt32(fileLength % Constants.FileChunkSize));
            byte[] fileNameLength  = FileHeaders.GetFileNameLength(inputFilePath);
            byte[] fileHeader      = Utilities.ConcatArrays(keyCommitmentBlock, lastChunkLength, fileNameLength, dataEncryptionKey);
            byte[] additionalData  = HeaderEncryption.ComputeAdditionalData(fileLength);
            return(HeaderEncryption.Encrypt(fileHeader, nonce, keyEncryptionKey, additionalData));
        }
Exemple #22
0
        public static byte[] GetAdditionalData(string inputFilePath)
        {
            byte[] magicBytes    = FileHeaders.ReadMagicBytes(inputFilePath);
            byte[] formatVersion = FileHeaders.ReadFileFormatVersion(inputFilePath);
            FileHeaders.ValidateFormatVersion(inputFilePath, formatVersion, Constants.EncryptionVersion);
            long fileLength    = FileHandling.GetFileLength(inputFilePath);
            int  headersLength = FileHeaders.GetHeadersLength();

            byte[] ciphertextLength = BitConverter.GetBytes(fileLength - headersLength);
            return(Utilities.ConcatArrays(magicBytes, formatVersion, ciphertextLength));
        }
        private static byte[] GetFileBytes(string filePath, bool preHashed)
        {
            int  oneGibibyte = 1024 * Constants.Mebibyte;
            long fileSize    = FileHandling.GetFileLength(filePath);

            if (fileSize >= oneGibibyte || preHashed)
            {
                using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan);
                return(Blake2.Hash(fileStream));
            }
            return(File.ReadAllBytes(filePath));
        }
Exemple #24
0
 private static void Finalize(string inputFilePath, string outputFilePath)
 {
     if (Globals.Overwrite)
     {
         FileHandling.OverwriteFile(inputFilePath, outputFilePath);
     }
     else if (Globals.ObfuscateFileNames)
     {
         RestoreFileName.RemoveAppendedFileName(inputFilePath);
     }
     FileHandling.MakeFileReadOnly(outputFilePath);
 }
Exemple #25
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 #26
0
        private static void CreateSignatureFile(string filePath, string signatureFilePath, byte[] signatureFileBytes, byte[] globalSignature)
        {
            const int offset = 0;

            if (string.IsNullOrEmpty(signatureFilePath))
            {
                signatureFilePath = filePath + Constants.SignatureExtension;
            }
            FileHandling.SetFileAttributesNormal(signatureFilePath);
            using var signatureFile = new FileStream(signatureFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan);
            signatureFile.Write(signatureFileBytes, offset, signatureFileBytes.Length);
            signatureFile.Write(globalSignature, offset, globalSignature.Length);
            File.SetAttributes(signatureFilePath, FileAttributes.ReadOnly);
        }
        private static string BackupDirectory(string directoryPath)
        {
            if (Globals.Overwrite)
            {
                return(null);
            }
            DisplayMessage.FilePathMessage(directoryPath, "Copying directory because you didn't specify -o|--overwrite...");
            string destinationDirectoryPath = FileHandling.GetUniqueDirectoryPath($"{directoryPath} - Copy");

            FileHandling.CopyDirectory(directoryPath, destinationDirectoryPath, copySubdirectories: true);
            if (!Globals.ObfuscateFileNames)
            {
                DisplayMessage.FileEncryptionResult(directoryPath, destinationDirectoryPath);
            }
            return(destinationDirectoryPath);
        }
Exemple #28
0
 public static void RemoveAppendedFileName(string inputFilePath)
 {
     try
     {
         File.SetAttributes(inputFilePath, FileAttributes.Normal);
         Encoding fileEncoding  = FileHandling.GetFileEncoding(inputFilePath);
         string   fileName      = Path.GetFileName(inputFilePath);
         byte[]   fileNameBytes = fileEncoding.GetBytes(fileName);
         using var fileStream = new FileStream(inputFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess);
         fileStream.SetLength(fileStream.Length - fileNameBytes.Length);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccess(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Error);
         DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to remove appended file name.");
     }
 }
        public static string GetOutputFilePath(string inputFilePath)
        {
            try
            {
                if (Globals.ObfuscateFileNames)
                {
                    ObfuscateFileName.AppendFileName(inputFilePath);
                    inputFilePath = ObfuscateFileName.ReplaceFilePath(inputFilePath);
                }
            }
            catch (Exception ex) when(ExceptionFilters.FileAccess(ex) || ex is EncoderFallbackException)
            {
                DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to store file name.");
            }
            string outputFilePath = inputFilePath + Constants.EncryptedExtension;

            return(FileHandling.GetUniqueFilePath(outputFilePath));
        }
Exemple #30
0
 private static IEnumerable <string> GetSignatureFileError(string signatureFilePath)
 {
     if (string.IsNullOrEmpty(signatureFilePath))
     {
         yield return("Please specify a signature file.");
     }
     else
     {
         bool?validMagicBytes = FileHandling.IsSignatureFile(signatureFilePath);
         if (validMagicBytes == null)
         {
             yield return("Unable to access signature file.");
         }
         if (validMagicBytes == false)
         {
             yield return(_invalidSignatureFile);
         }
     }
 }