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 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); } } }
public static byte[] GetAdditionalData(FileStream inputFile, byte[] ephemeralPublicKey) { byte[] ciphertextLength = BitConversion.GetBytes(inputFile.Length - Constants.FileHeadersLength); byte[] magicBytes = FileHeaders.ReadMagicBytes(inputFile); byte[] formatVersion = FileHeaders.ReadFileFormatVersion(inputFile); FileHeaders.ValidateFormatVersion(formatVersion, Constants.EncryptionVersion); return(Arrays.Concat(ciphertextLength, magicBytes, formatVersion, ephemeralPublicKey)); }
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)); }
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)); }
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)); }
public static bool?IsKryptorFile(string filePath) { try { byte[] magicBytes = FileHeaders.ReadMagicBytes(filePath); return(Utilities.Compare(magicBytes, Constants.KryptorMagicBytes)); } catch (Exception ex) when(ExceptionFilters.FileAccess(ex)) { return(null); } }
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); } }
private static void Decrypt(FileStream inputFile, FileStream outputFile, byte[] nonce, byte[] dataEncryptionKey, byte[] additionalData, int lastChunkLength) { int headersLength = FileHeaders.GetHeadersLength(); inputFile.Seek(headersLength, SeekOrigin.Begin); const int offset = 0; byte[] ciphertextChunk = new byte[Constants.TotalChunkLength]; while (inputFile.Read(ciphertextChunk, offset, ciphertextChunk.Length) > 0) { byte[] plaintextChunk = SecretAeadXChaCha20Poly1305.Decrypt(ciphertextChunk, nonce, dataEncryptionKey, additionalData); ChunkHandling.ValidateKeyCommitmentBlock(plaintextChunk); nonce = Sodium.Utilities.Increment(nonce); additionalData = ChunkHandling.GetPreviousPoly1305Tag(ciphertextChunk); plaintextChunk = ChunkHandling.RemoveKeyCommitmentBlock(plaintextChunk); outputFile.Write(plaintextChunk, offset, plaintextChunk.Length); } outputFile.SetLength((outputFile.Length - Constants.FileChunkSize) + lastChunkLength); Utilities.ZeroArray(dataEncryptionKey); }
public static bool VerifySignature(string signatureFilePath, string filePath, byte[] publicKey, out string comment) { using var signatureFile = new FileStream(signatureFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan); byte[] magicBytes = GetMagicBytes(signatureFile); byte[] formatVersion = GetFormatVersion(signatureFile); FileHeaders.ValidateFormatVersion(formatVersion, Constants.SignatureVersion); byte[] preHashed = GetPreHashedHeader(signatureFile); byte[] fileSignature = GetFileSignature(signatureFile); byte[] commentBytes = GetCommentBytes(signatureFile); byte[] signatureFileBytes = Arrays.Concat(magicBytes, formatVersion, preHashed, fileSignature, commentBytes); bool validGlobalSignature = VerifyGlobalSignature(signatureFile, signatureFileBytes, publicKey); if (!validGlobalSignature) { comment = string.Empty; return(false); } bool preHash = BitConverter.ToBoolean(preHashed); byte[] fileBytes = GetFileBytes(filePath, preHash); comment = Encoding.UTF8.GetString(commentBytes); return(PublicKeyAuth.VerifyDetached(fileSignature, fileBytes, publicKey)); }
public static bool VerifySignature(string signatureFilePath, string filePath, byte[] publicKey) { using var signatureFile = new FileStream(signatureFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess); // Verify the global signature byte[] magicBytes = GetMagicBytes(signatureFile); byte[] formatVersion = GetFormatVersion(signatureFile); FileHeaders.ValidateFormatVersion(signatureFilePath, formatVersion, Constants.SignatureVersion); byte[] preHashedHeader = GetPreHashedHeader(signatureFile); byte[] fileSignature = GetFileSignature(signatureFile); _commentBytes = GetCommentBytes(signatureFile); byte[] signatureFileBytes = Utilities.ConcatArrays(magicBytes, formatVersion, preHashedHeader, fileSignature, _commentBytes); bool validGlobalSignature = VerifyGlobalSignature(signatureFile, signatureFileBytes, publicKey); if (!validGlobalSignature) { return(false); } // Verify the file signature bool preHashed = BitConverter.ToBoolean(preHashedHeader); byte[] fileBytes = GetFileBytes(filePath, preHashed); return(PublicKeyAuth.VerifyDetached(fileSignature, fileBytes, publicKey)); }
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; } }