public CryptoContainer ValidateDecrypt(CryptoRequest request) { CryptoContainer container = null; if (!request.SkipValidations) { container = CryptoContainer.CreateForDecryption(request); var validationResult = container.ReadAndValidateDataForDecryption(); if (!validationResult.IsValid) { throw validationResult.ExceptionToThrow ?? new Exception("Unknown error"); } request.IV = container.GetIV(); if (request.Password != null) { request.Key = container.CalculateKey(); } } if (request.Key == null || request.Key.Length != 32) { throw new ArgumentException("Key must be 32 bytes long."); } if (request.IV == null || request.IV.Length != 16) { throw new ArgumentException($"IV must be 16 bytes in length"); } return(container); }
private CryptoContainer(CryptoRequest request, bool createForEncryption) { if (request.EmbedSalt) { Flags = CryptoContainerFlags.HasSalt; Salt = request.Salt; } else { Salt = new byte[32]; } if (!createForEncryption) { Salt = request.Salt; } IV = request.IV; if (createForEncryption) { OutData = request.OutData; } else { InData = request.InData; long currentPosition = InData.Position; InData.Position = 0; _headerData = new byte[HeaderSize]; InData.Read(_headerData, 0, HeaderSize); InData.Position = 0; } Key = request.Key; _password = request.Password; }
private static ICryptoTransform GetDecryptorAndSetAes(AesManaged aes, CryptoRequest request) #endif { aes.IV = request.IV; aes.Key = request.Key; // aes.Padding = PaddingMode.PKCS7; // aes.BlockSize = 128; return(aes.CreateDecryptor()); }
internal static void Decrypt(CryptoRequest request) { CryptoContainer container = null; if (!request.SkipValidations) { container = CryptoContainer.CreateForDecryption(request); var validationResult = container.ReadAndValidateDataForDecryption(); if (!validationResult.IsValid) { throw validationResult.ExceptionToThrow ?? new Exception("Unknown error"); } request.IV = container.GetIV(); if (request.Password != null) { request.Key = container.CalculateKey(); } } if (request.Key == null || request.Key.Length != 32) { throw new ArgumentException("Key must be 32 bytes long."); } if (request.IV == null || request.IV.Length != 16) { throw new ArgumentException($"IV must be 16 bytes in length"); } using (var aes = new AesManaged()) { aes.IV = request.IV; aes.Key = request.Key; aes.Padding = PaddingMode.ISO10126; if (request.SkipValidations) { aes.Padding = PaddingMode.PKCS7; } aes.BlockSize = 128; using (var decryptor = aes.CreateDecryptor()) { CryptoStream cs = new CryptoStream(request.OutData, decryptor, CryptoStreamMode.Write); int bufferSize = aes.BlockSize; byte[] buffer = new byte[bufferSize]; int read = 0; while ((read = request.InData.Read(buffer, 0, bufferSize)) > 0) { cs.Write(buffer, 0, read); cs.Flush(); } cs.FlushFinalBlock(); } } }
internal static void Encrypt(CryptoRequest request) { if (request.Key.Length != 32) { throw new ArgumentException("Key must be 32 bytes long."); } if (request.IV == null || request.IV.Length != 16) { throw new ArgumentException("IV must be 16 bytes in length"); } CryptoContainer container = null; if (!request.SkipValidations) { container = CryptoContainer.CreateForEncryption(request); container.WriteEmptyHeaderData(); } using (var aes = new AesManaged()) { aes.IV = request.IV; aes.Key = request.Key; aes.Padding = PaddingMode.ISO10126; aes.BlockSize = 128; if (request.SkipValidations) { aes.Padding = PaddingMode.PKCS7; } using (var encryptor = aes.CreateEncryptor()) { CryptoStream cs = new CryptoStream(request.OutData, encryptor, CryptoStreamMode.Write); int bufferSize = aes.BlockSize; byte[] buffer = new byte[bufferSize]; int read = 0; while ((read = request.InData.Read(buffer, 0, bufferSize)) > 0) { cs.Write(buffer, 0, read); cs.Flush(); } cs.FlushFinalBlock(); } } if (!request.SkipValidations) { container.WriteChecksAndEmbeddedData(); } }
internal static async Task EncryptAsync(CryptoRequest request) { CryptoContainer container = request.ValidateEncryption(); ReportAndCancellationToken token = request.Token ?? new ReportAndCancellationToken(); token.CanReportProgress = request.InData.CanSeek; using (var aes = GetAes()) using (var encryptor = GetEncryptorAndSetAes(aes, request)) { int bufferSize = aes.BlockSize; if (token.CanReportProgress ?? false) { token.NumberOfIterations = (int)Math.Ceiling(request.InData.Length / (double)bufferSize); } CryptoStream cs = new CryptoStream(request.OutData, encryptor, CryptoStreamMode.Write); byte[] buffer = new byte[bufferSize]; int read = 0; int iterationCount = 0; while ((read = await request.InData.ReadAsync(buffer, 0, bufferSize)) > 0) { await cs.WriteAsync(buffer, 0, read); await cs.FlushAsync(); if (token.IsCanceled) { break; } iterationCount++; token.ReportProgressInternal(iterationCount); } if (token.IsCanceled) { return; } cs.FlushFinalBlock(); } if (!request.SkipValidations) { await container.WriteChecksAndEmbeddedDataAsync(); } }
internal static void Decrypt(CryptoRequest request) { CryptoContainer container = request.ValidateDecrypt(request); ReportAndCancellationToken token = request.Token ?? new ReportAndCancellationToken(); token.CanReportProgress = request.InData.CanSeek; using (var aes = GetAes()) using (ICryptoTransform decryptor = GetDecryptorAndSetAes(aes, request)) { int bufferSize = aes.BlockSize; if (token.CanReportProgress ?? false) { token.NumberOfIterations = (int)Math.Ceiling(request.InData.Length / (double)bufferSize); } CryptoStream cs = new CryptoStream(request.OutData, decryptor, CryptoStreamMode.Write); byte[] buffer = new byte[bufferSize]; int read = 0; int iterationCount = 0; while ((read = request.InData.Read(buffer, 0, bufferSize)) > 0) { cs.Write(buffer, 0, read); cs.Flush(); if (token.IsCanceled) { break; } iterationCount++; token.ReportProgressInternal(iterationCount); } if (token.IsCanceled) { return; } cs.FlushFinalBlock(); } }
public static CryptoContainer CreateForDecryption(CryptoRequest request) => new CryptoContainer(request, false);
public static CryptoContainer CreateForEncryption(CryptoRequest request) => new CryptoContainer(request, true);
internal static ValidationResult ValidateEncryptedData(CryptoRequest request) => CryptoContainer.CreateForDecryption(request).ReadAndValidateDataForDecryption();
private static ICryptoTransform GetDecryptorAndSetAes(Aes aes, CryptoRequest request)