public static void SignEachFile(string[] filePaths, string signatureFilePath, string comment, bool preHash, byte[] privateKey) { privateKey = PrivateKey.Decrypt(privateKey); if (privateKey == null) { return; } if (string.IsNullOrEmpty(comment)) { comment = _defaultComment; } foreach (string filePath in filePaths) { try { DigitalSignatures.SignFile(filePath, signatureFilePath, comment, preHash, privateKey); DisplayMessage.FilePathMessage(filePath, "File signed successfully."); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { DisplayMessage.FilePathException(filePath, ex.GetType().Name, "Unable to create signature."); } } CryptographicOperations.ZeroMemory(privateKey); }
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 = KeyExchange.GetEphemeralSharedSecret(recipientPublicKey, out byte[] ephemeralPublicKey); byte[] salt = Generate.Salt(); byte[] keyEncryptionKey = Generate.KeyEncryptionKey(sharedSecret, ephemeralSharedSecret, salt); string outputFilePath = GetOutputFilePath(inputFilePath); EncryptFile.Initialize(inputFilePath, outputFilePath, ephemeralPublicKey, salt, keyEncryptionKey); CryptographicOperations.ZeroMemory(keyEncryptionKey); EncryptionSuccessful(inputFilePath, outputFilePath); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Error); DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to encrypt the file."); } }
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; } }
private static void DecryptEachFileWithPrivateKey(string[] filePaths, byte[] privateKey) { foreach (string inputFilePath in filePaths) { bool validFilePath = FilePathValidation.FileDecryption(inputFilePath); if (!validFilePath) { --Globals.TotalCount; continue; } try { 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(privateKey, ephemeralPublicKey); byte[] salt = FileHeaders.ReadSalt(inputFile); byte[] keyEncryptionKey = Generate.KeyEncryptionKey(ephemeralSharedSecret, salt); DecryptInputFile(inputFile, ephemeralPublicKey, keyEncryptionKey); CryptographicOperations.ZeroMemory(keyEncryptionKey); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { FileException(inputFilePath, ex); } } }
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)) { Logging.LogException(ex.ToString(), Logging.Severity.Error); DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to encrypt the file."); } }
public static void VerifyFile(byte[] publicKey, string signatureFilePath, string filePath) { try { bool validSignature = DigitalSignatures.VerifySignature(signatureFilePath, filePath, publicKey); if (!validSignature) { DisplayMessage.FilePathMessage(filePath, "Bad signature."); return; } DisplayMessage.FilePathMessage(filePath, "Good signature."); string comment = DigitalSignatures.GetComment(); DisplayMessage.Message($"Authenticated comment: {comment}"); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Error); if (ex is ArgumentOutOfRangeException) { DisplayMessage.Exception(ex.GetType().Name, ex.Message); return; } DisplayMessage.Exception(ex.GetType().Name, "Unable to verify signature."); } }
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); }
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); } }
private static void EncryptInputFile(string inputFilePath, string outputFilePath, byte[] ephemeralPublicKey, byte[] salt, byte[] keyEncryptionKey) { try { EncryptFile.Initialize(inputFilePath, outputFilePath, ephemeralPublicKey, salt, keyEncryptionKey); FileEncryption.EncryptionSuccessful(inputFilePath, outputFilePath); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { DisplayMessage.FilePathException(inputFilePath, ex.GetType().Name, "Unable to encrypt the file."); } }
private static void DecryptInputFile(string inputFilePath, byte[] keyEncryptionKey) { try { string outputFilePath = FileDecryption.GetOutputFilePath(inputFilePath); DecryptFile.Initialize(inputFilePath, outputFilePath, keyEncryptionKey); FileDecryption.DecryptionSuccessful(inputFilePath, outputFilePath); } catch (Exception ex) when(ExceptionFilters.Cryptography(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."); } }
public static void VerifyFile(string signatureFilePath, string filePath, byte[] publicKey) { try { bool validSignature = DigitalSignatures.VerifySignature(signatureFilePath, filePath, publicKey, out string comment); if (!validSignature) { DisplayMessage.FilePathMessage(filePath, "Bad signature."); return; } DisplayMessage.FilePathMessage(filePath, "Good signature."); DisplayMessage.Message($"Authenticated comment: {comment}"); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { if (ex is ArgumentException) { DisplayMessage.FilePathMessage(signatureFilePath, ex.Message); return; } DisplayMessage.Exception(ex.GetType().Name, "Unable to verify signature."); } }
public static void Initialize(FileStream inputFile, string outputFilePath, byte[] ephemeralPublicKey, byte[] keyEncryptionKey) { var dataEncryptionKey = new byte[Constants.EncryptionKeyLength]; try { byte[] encryptedHeader = FileHeaders.ReadEncryptedHeader(inputFile); byte[] nonce = FileHeaders.ReadNonce(inputFile); byte[] header = DecryptFileHeader(inputFile, ephemeralPublicKey, encryptedHeader, nonce, keyEncryptionKey); if (header == null) { throw new ArgumentException("Incorrect password/key or this file has been tampered with."); } int lastChunkLength = FileHeaders.GetLastChunkLength(header); int fileNameLength = FileHeaders.GetFileNameLength(header); dataEncryptionKey = FileHeaders.GetDataEncryptionKey(header); CryptographicOperations.ZeroMemory(header); using (var outputFile = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan)) { nonce = Utilities.Increment(nonce); byte[] additionalData = ChunkHandling.GetPreviousTag(encryptedHeader); Decrypt(inputFile, outputFile, nonce, dataEncryptionKey, additionalData, lastChunkLength); } string inputFilePath = inputFile.Name; inputFile.Dispose(); Finalize(inputFilePath, outputFilePath, fileNameLength); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { CryptographicOperations.ZeroMemory(dataEncryptionKey); if (!(ex is ArgumentException)) { FileHandling.DeleteFile(outputFilePath); } throw; } }
public static void Initialize(string inputFilePath, string outputFilePath, byte[] ephemeralPublicKey, byte[] salt, byte[] keyEncryptionKey) { byte[] dataEncryptionKey = Generate.DataEncryptionKey(); try { 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)) { byte[] nonce = Generate.Nonce(); byte[] encryptedHeader = EncryptFileHeader(inputFilePath, dataEncryptionKey, nonce, keyEncryptionKey); FileHeaders.WriteHeaders(outputFile, ephemeralPublicKey, salt, nonce, encryptedHeader); nonce = Sodium.Utilities.Increment(nonce); byte[] additionalData = ChunkHandling.GetPreviousPoly1305Tag(encryptedHeader); Encrypt(inputFile, outputFile, nonce, dataEncryptionKey, additionalData); } Finalize(inputFilePath, outputFilePath); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { FileHandling.DeleteFile(outputFilePath); Utilities.ZeroArray(dataEncryptionKey); throw; } }