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)) { // 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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to authenticate the file."); storedHash = null; return(true); } }
private static byte[] GetKeyfileBytes(byte[] passwordBytes) { if (!string.IsNullOrEmpty(Globals.KeyfilePath)) { byte[] keyfileBytes = Keyfiles.ReadKeyfile(Globals.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); }
public static (byte[], byte[]) 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); }
private static byte[] ComputeFileHash(string encryptedFilePath, byte[] macKey) { try { byte[] computedHash = new byte[Constants.HashLength]; using (var fileStream = new FileStream(encryptedFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { MemoryEncryption.DecryptByteArray(ref macKey); computedHash = HashingAlgorithms.Blake2(fileStream, macKey); MemoryEncryption.EncryptByteArray(ref macKey); } return(computedHash); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(encryptedFilePath, ex.GetType().Name, "Unable to compute MAC."); return(null); } }