Beispiel #1
0
        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);
        }
Beispiel #2
0
        /// <summary>
        /// Adds additional data to encrypted data. Additional data is not protected, but it isn't added in plain text either.
        /// </summary>
        /// <param name="encryptedData">The encrypted data to which to add additional data.</param>
        /// <param name="additionalData">The additional data to add. Dictionary items where key or value is null or empty will be ignored/</param>
        /// <param name="destination">Stream to which to write encrypted data with added additional data</param>
        public static void AddAdditionalData(Stream encryptedData, Dictionary <string, string> additionalData, Stream destination)
        {
            if (additionalData == null)
            {
                throw new ArgumentNullException(nameof(additionalData));
            }

            byte[] dataBytes = new AdditionalData(additionalData).GetBytes();
            CryptoContainer.WriteAdditionalData(encryptedData, dataBytes, destination);
        }
Beispiel #3
0
        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();
                }
            }
        }
Beispiel #4
0
        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();
            }
        }
Beispiel #5
0
        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();
            }
        }
Beispiel #6
0
        public CryptoContainer ValidateEncryption()
        {
            if (Key.Length != 32)
            {
                throw new ArgumentException("Key must be 32 bytes long.");
            }
            if (IV == null || IV.Length != 16)
            {
                throw new ArgumentException("IV must be 16 bytes in length");
            }

            CryptoContainer container = null;

            if (!SkipValidations)
            {
                container = CryptoContainer.CreateForEncryption(this);
                container.WriteEmptyHeaderData();
            }

            return(container);
        }
Beispiel #7
0
        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();
                }
        }
Beispiel #8
0
 internal static ValidationResult ValidateEncryptedData(CryptoRequest request)
 => CryptoContainer.CreateForDecryption(request).ReadAndValidateDataForDecryption();
Beispiel #9
0
 /// <summary>
 /// Reads the additional data from encrypted data if present.
 /// </summary>
 /// <param name="encryptedData">The encrypted data.</param>
 /// <returns>Additional data</returns>
 public static Dictionary <string, string> ReadAdditionalData(Stream encryptedData)
 {
     byte[] data = CryptoContainer.ReadAdditionalData(encryptedData);
     return(AdditionalData.LoadFromBytes(data).Data);
 }