public static void RestoreOriginalFileName(string decryptedFilePath) { try { if (Globals.AnonymousRename == true) { string originalFileName = ReadOriginalFileName(decryptedFilePath); if (!string.IsNullOrEmpty(originalFileName)) { string anonymousFileName = Path.GetFileName(decryptedFilePath); string originalFilePath = Regex.Replace(decryptedFilePath, anonymousFileName, originalFileName); if (File.Exists(originalFilePath)) { // Replace the file File.Delete(originalFilePath); } File.Move(decryptedFilePath, originalFilePath); } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(decryptedFilePath, ex.GetType().Name, "Unable to restore original file name."); } }
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>()); } }
public static void RestoreDirectoryName(string folderPath) { try { NullChecks.Strings(folderPath); string anonymisedDirectoryName = Path.GetFileName(folderPath); // Get the path where the original directory name is stored string storageFileName = $"{anonymisedDirectoryName}.txt"; string storageFilePath = Path.Combine(folderPath, storageFileName); if (File.Exists(storageFilePath)) { string originalDirectoryName = File.ReadAllText(storageFilePath); string originalDirectoryPath = folderPath.Replace(anonymisedDirectoryName, originalDirectoryName); Directory.Move(folderPath, originalDirectoryPath); storageFilePath = Path.Combine(originalDirectoryPath, storageFileName); if (File.Exists(storageFilePath)) { File.Delete(storageFilePath); } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(folderPath, ex.GetType().Name, "Unable to restore original directory name."); } }
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); } }
public static byte[] GetPrivateKeyFromFile(string privateKeyPath) { try { string encodedPrivateKey = File.ReadAllText(privateKeyPath); if (encodedPrivateKey.Length != Constants.EncryptionPrivateKeyLength && encodedPrivateKey.Length != Constants.SigningPrivateKeyLength) { DisplayMessage.Error(ValidationMessages.PrivateKeyFile); return(null); } byte[] privateKey = Convert.FromBase64String(encodedPrivateKey); ValidateKeyVersion(privateKey); return(privateKey); } catch (Exception ex) when(ExceptionFilters.AsymmetricKeyHandling(ex)) { if (ex is ArgumentOutOfRangeException) { DisplayMessage.Exception(ex.GetType().Name, ex.Message); return(null); } DisplayMessage.Exception(ex.GetType().Name, "Unable to retrieve private key."); return(null); } }
private static void CallEncryption(bool encryption, string filePath, byte[] passwordBytes) { try { bool kryptorExtension = filePath.EndsWith(Constants.EncryptedExtension, StringComparison.Ordinal); // Prevent Read-Only file attribute causing errors File.SetAttributes(filePath, FileAttributes.Normal); if (encryption == true && kryptorExtension == false) { Encryption.InitializeEncryption(filePath, passwordBytes); OverwriteDisabled(filePath); } else if (encryption == false && kryptorExtension == true) { Decryption.InitializeDecryption(filePath, passwordBytes); } else { DisplayMessage.FileError(filePath, encryption, kryptorExtension); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to set file attributes to normal."); } }
private static void RetrieveArgon2Parameters(string filePath, ref string memorySize, ref string iterations) { try { // Read the first line of the file using var streamReader = new StreamReader(filePath, true); string firstLine = streamReader.ReadLine(); int memorySizeIndex = firstLine.IndexOf(Constants.MemorySizeFlag, StringComparison.Ordinal); if (memorySizeIndex != -1) { int iterationsIndex = firstLine.IndexOf(Constants.IterationsFlag, StringComparison.Ordinal); int endIndex = firstLine.IndexOf(Constants.EndFlag, StringComparison.Ordinal); // If the strings are found on the line if (memorySizeIndex != -1 && iterationsIndex != -1 && endIndex != -1) { memorySize = firstLine.Substring(memorySizeIndex, iterationsIndex - memorySizeIndex); iterations = firstLine.Substring(iterationsIndex, endIndex - iterationsIndex); } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex) || ExceptionFilters.CharacterEncodingExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to read Argon2 parameters from the file."); } }
private static string[] GetRandomWords(string wordListFilePath, int[] lineNumbers, int wordCount, bool upperCase, bool numbers) { try { string[] words = new string[wordCount]; for (int i = 0; i < wordCount; i++) { words[i] = File.ReadLines(wordListFilePath).Skip(lineNumbers[i]).Take(1).First(); // Remove any numbers/spaces on the line words[i] = Regex.Replace(words[i], @"[\d-]", string.Empty).Trim(); if (upperCase == true) { words[i] = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(words[i].ToLower(CultureInfo.CurrentCulture)); } if (numbers == true) { words[i] += words[i].Length; } } return(words); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex) || ex is RegexMatchTimeoutException) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.Error(ex.GetType().Name, "Unable to retrieve words from the wordlist."); return(null); } }
public static char[] GenerateRandomPassphrase(int wordCount, bool uppercase, bool numbers) { try { string wordlistFilePath = Path.Combine(Constants.KryptorDirectory, "wordlist.txt"); if (File.Exists(wordlistFilePath)) { List <char> passphrase = new List <char>(); int wordlistLength = File.ReadLines(wordlistFilePath).Count(); int[] lineNumbers = GenerateLineNumbers(wordlistLength, wordCount); string[] words = GetRandomWords(wordlistFilePath, lineNumbers, wordCount, uppercase, numbers); Array.Clear(lineNumbers, 0, lineNumbers.Length); if (words != null) { FormatPassphrase(words, ref passphrase, wordCount); Array.Clear(words, 0, words.Length); } return(passphrase.ToArray()); } else { File.WriteAllText(wordlistFilePath, Properties.Resources.wordlist); return(GenerateRandomPassphrase(wordCount, uppercase, numbers)); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.Error(ex.GetType().Name, "Unable to generate a random passphrase."); return(Array.Empty <char>()); } }
public static void OpenLink(string link) { try { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Process.Start(new ProcessStartInfo("cmd", $"/c start {link}") { CreateNoWindow = true }); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Process.Start("xdg-open", link); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { Process.Start("open", link); } } catch (Exception ex) when(ExceptionFilters.OpenLinkExceptions(ex)) { DisplayMessage.Error(ex.GetType().Name, $"Unable to automatically open link. Please visit {link} manually using your browser."); } }
public static void Encrypt(bool usePassword, string keyfile, string privateKey, string publicKey, string[] filePaths) { if (usePassword || !string.IsNullOrEmpty(keyfile)) { char[] password = Array.Empty <char>(); if (usePassword) { password = PasswordPrompt.EnterNewPassword(); } FileEncryptionWithPassword(password, keyfile, filePaths); } else if (!string.IsNullOrEmpty(publicKey) && !string.IsNullOrEmpty(privateKey)) { if (publicKey.EndsWith(Constants.PublicKeyExtension)) { FileEncryptionWithPublicKey(privateKey, publicKey, filePaths); return; } // Use private key string FileEncryptionWithPublicKey(privateKey, publicKey.ToCharArray(), filePaths); } else if (!string.IsNullOrEmpty(privateKey)) { FileEncryptionWithPrivateKey(privateKey, filePaths); } else { DisplayMessage.Error("Please either specify a (password and/or keyfile), (private key and public key), or private key."); } }
public static bool AuthenticateFile(string filePath, byte[] macKey, out byte[] storedHash) { try { bool tampered = true; storedHash = ReadStoredHash(filePath); if (storedHash != null) { byte[] computedHash = new byte[Constants.HashLength]; using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, Constants.FileBufferSize, FileOptions.SequentialScan)) { // Remove the stored MAC from the file before computing the MAC fileStream.SetLength(fileStream.Length - computedHash.Length); MemoryEncryption.DecryptByteArray(ref macKey); computedHash = HashingAlgorithms.Blake2(fileStream, macKey); MemoryEncryption.EncryptByteArray(ref macKey); } // Invert result tampered = !Sodium.Utilities.Compare(storedHash, computedHash); if (tampered == true) { // Restore the stored MAC AppendHash(filePath, storedHash); } } return(tampered); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to authenticate the file."); storedHash = null; return(true); } }
public static void ReadSettings() { try { if (File.Exists(_settingsFile)) { string[] settingsLines = File.ReadAllLines(_settingsFile); var settings = new List <string>(); foreach (string line in settingsLines) { string[] splitLine = line.Split(':'); // Ignore the name of each setting - only store values settings.Add(splitLine[1]); } LoadSettings(settings); } else { // Create settings file with default settings SaveSettings(); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(ex.GetType().Name, "Unable to read the settings file."); } }
public static void SaveSettings() { try { if (File.Exists(_settingsFile)) { var settings = new Dictionary <string, string> { { "Memory Encryption", Globals.MemoryEncryption.ToString() }, { "Anonymous Rename", Globals.AnonymousRename.ToString() }, { "Overwrite Files", Globals.OverwriteFiles.ToString() }, { "Argon2 Memory Size", Invariant.ToString(Globals.MemorySize) }, { "Argon2 Iterations", Invariant.ToString(Globals.Iterations) }, }; using var streamWriter = new StreamWriter(_settingsFile); foreach (var keyValuePair in settings) { streamWriter.WriteLine($"{keyValuePair.Key}: {keyValuePair.Value}"); } } else { File.Create(_settingsFile).Close(); SaveSettings(); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(ex.GetType().Name, "Unable to save settings."); } }
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); } }
private static void RetypeNewPassword(char[] password) { Console.WriteLine("Retype password:"******"Passwords do not match."); Environment.Exit(13); } }
public static char[] EnterYourPassword() { Console.WriteLine("Enter your password:"******"Password cannot be empty."); Environment.Exit(13); } return(password); }
public static bool FileEncryption(string inputFilePath) { string errorMessage = GetFileEncryptionError(inputFilePath); if (string.IsNullOrEmpty(errorMessage)) { return(true); } DisplayMessage.Error(errorMessage); return(false); }
public static void MakeFileReadOnly(string filePath) { try { File.SetAttributes(filePath, FileAttributes.ReadOnly); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to make the file read-only."); } }
private static bool?LoadBooleanSetting(string setting) { try { return(Invariant.ToBoolean(setting)); } catch (Exception ex) when(ExceptionFilters.SettingsExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Low); DisplayMessage.Error(ex.GetType().Name, $"Unable to convert {setting} setting to boolean."); return(null); } }
public static void OverwriteFile(string fileToDelete, string fileToCopy) { try { File.Copy(fileToCopy, fileToDelete, true); File.Delete(fileToDelete); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.Error(fileToDelete, ex.GetType().Name, "Unable to overwrite and/or delete."); } }
private static string[] GetAllDirectories(string folderPath) { try { return(Directory.GetDirectories(folderPath, "*", SearchOption.AllDirectories)); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(folderPath, ex.GetType().Name, "Unable to get subdirectories in selected folder."); return(null); } }
private static int GetFileNameLength(string filePath, string originalFileName) { try { EncodeFileName(filePath, originalFileName, out byte[] newLineBytes, out byte[] fileNameBytes); return(newLineBytes.Length + fileNameBytes.Length); } catch (Exception ex) when(ExceptionFilters.CharacterEncodingExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to remove the original file name stored in the file. The length of the stored file name could not be calculated."); return(0); } }
public static byte[] Decrypt(byte[] privateKey) { try { char[] password = PasswordPrompt.EnterYourPassword(); byte[] passwordBytes = Password.Hash(password); return(Decrypt(passwordBytes, privateKey)); } catch (CryptographicException) { DisplayMessage.Error("Incorrect password or the private key has been tampered with."); return(null); } }
public static void LogException(string exceptionMessage, Severity severity) { try { const string logFileName = "error log.txt"; string logFilePath = Path.Combine(Constants.KryptorDirectory, logFileName); string logMessage = $"[Error] Severity = {severity}" + Environment.NewLine + exceptionMessage + Environment.NewLine; File.AppendAllText(logFilePath, logMessage); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { DisplayMessage.Error(ex.GetType().Name, "Unable to log exception."); } }
public static bool?IsDirectory(string filePath) { try { var fileAttributes = File.GetAttributes(filePath); return(fileAttributes.HasFlag(FileAttributes.Directory)); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to check if file path is a directory."); return(null); } }
public static void DecryptByteArray(ref byte[] byteArray) { try { if (Globals.MemoryEncryption == true && byteArray != null) { byteArray = SealedPublicKeyBox.Open(byteArray, _keyPair); } } catch (Exception ex) when(ExceptionFilters.MemoryEncryptionExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Bug); DisplayMessage.Error(ex.GetType().Name, "Memory decryption failed. This is a bug - please report it."); } }
public static void DeleteFile(string filePath) { try { if (File.Exists(filePath)) { File.Delete(filePath); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to delete the file."); } }
public static bool FileDecryption(string inputFilePath) { if (inputFilePath.Contains(Constants.SaltFile)) { return(false); } string errorMessage = GetFileDecryptionError(inputFilePath); if (string.IsNullOrEmpty(errorMessage)) { return(true); } DisplayMessage.Error(errorMessage); return(false); }
private static void LoadSettings(List <string> settings) { try { Globals.MemoryEncryption = LoadBooleanSetting(settings[0]) ?? Globals.MemoryEncryption; Globals.AnonymousRename = LoadBooleanSetting(settings[1]) ?? Globals.AnonymousRename; Globals.OverwriteFiles = LoadBooleanSetting(settings[2]) ?? Globals.OverwriteFiles; Globals.MemorySize = LoadIntegerSetting(settings[3]) ?? Globals.MemorySize; Globals.Iterations = LoadIntegerSetting(settings[4]) ?? Globals.Iterations; } catch (IndexOutOfRangeException ex) { Logging.LogException(ex.ToString(), Logging.Severity.Bug); DisplayMessage.Error(ex.GetType().Name, "Error loading settings."); } }