public static async Task <Result> DecryptFileAsync( string encryptedFilePath, string privateKeyXmlFilePath, string encryptedFileInfoXmlFilePath) { Result decryptResult; try { var deserializationResult = EncryptedFileInfo.ReadFromFile(encryptedFileInfoXmlFilePath); if (deserializationResult.Failure) { return(Result.Fail( "An error occurred reading the encryption info XML file, unable to continue decrypting file.")); } var encryptionInfoXml = deserializationResult.Value; var privateKeyXml = CryptoKeys.ReadXmlKeyFromFile(privateKeyXmlFilePath); decryptResult = await Task.Factory.StartNew(() => Decrypt(encryptedFilePath, encryptionInfoXml, privateKeyXml)).ConfigureAwait(false); } catch (Exception ex) { return(Result.Fail($"{ex.Message} {ex.GetType()}")); } return(decryptResult); }
public static async Task <Result <EncryptedFileInfo> > EncryptFileAsync( string filePath, string publicKeyXmlFilePath, HashAlgorithmType hashAlgorithm = HashAlgorithmType.SHA2_256) { var folderPath = Path.GetDirectoryName(filePath); var encryptedFileName = $"{Path.GetFileName(filePath)}.encrypted"; var infoXmlFilePath = Path.Combine(folderPath, $"{encryptedFileName}.xml"); EncryptedFileInfo infoXml; try { var publicKeyXml = CryptoKeys.ReadXmlKeyFromFile(publicKeyXmlFilePath); infoXml = await Task.Factory.StartNew(() => Encrypt(filePath, publicKeyXml, hashAlgorithm)).ConfigureAwait(false); } catch (FileNotFoundException ex) { return(Result.Fail <EncryptedFileInfo>($"{ex.Message} {ex.GetType()}")); } var serializationResult = EncryptedFileInfo.SaveToFile(infoXml, infoXmlFilePath); return(serializationResult.Success ? Result.Ok(infoXml) : Result.Fail <EncryptedFileInfo>("Error occurred serializing encrypted file info to XML.")); }
static Result Decrypt(string encryptedFilePath, EncryptedFileInfo encryptionInfoXml, string privateKeyXml) { var folderPath = Path.GetDirectoryName(encryptedFilePath); var filePath = Path.Combine(folderPath, encryptionInfoXml.FileName); var aesKey = DecryptBytesRsa(Convert.FromBase64String(encryptionInfoXml.EncryptedAesKey), privateKeyXml); var aesIv = DecryptBytesRsa(Convert.FromBase64String(encryptionInfoXml.EncryptedAesIv), privateKeyXml); var signatureKey = DecryptBytesRsa(Convert.FromBase64String(encryptionInfoXml.EncryptedFileDigestKey), privateKeyXml); var signatureCalculated = Convert.ToBase64String(CryptoHashers.CalculateFileDigest(encryptedFilePath, encryptionInfoXml.FileDigestHashAlgorithmType, signatureKey)); var signatureTransmitted = encryptionInfoXml.EncryptedFileDigest; if (signatureTransmitted != signatureCalculated) { return(Result.Fail( "File manifest calculated for the encrypted file does not match the value in the XML doc. File may have been modified, aborting decryption operation.")); } using (var aes = new AesCryptoServiceProvider { KeySize = 128, Key = aesKey, IV = aesIv }) using (var decryptor = aes.CreateDecryptor()) using (var fsPlain = File.Open(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) using (var fsEncrypted = File.Open(encryptedFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var cs = new CryptoStream(fsPlain, decryptor, CryptoStreamMode.Write)) { fsEncrypted.CopyTo(cs); } return(Result.Ok()); }
public static Result SaveToFile(EncryptedFileInfo fileInfo, string filePath) { try { var serializer = new XmlSerializer(typeof(EncryptedFileInfo)); using (var writer = new StreamWriter(filePath)) { serializer.Serialize(writer, fileInfo); } } catch (FileNotFoundException ex) { return(Result.Fail <EncryptedFileInfo>($"{ex.Message} ({ex.GetType()})")); } return(Result.Ok()); }