/// <summary> /// Initializes a new instance of the <see cref="SymmetricDecryptStream" /> class. /// </summary> /// <param name="stream"> /// The inner <see cref="Stream" /> to read the encrypted message from. /// </param> /// <param name="settings"> /// The <see cref="SymmetricDecryptionSettings" /> specifying the cryptographic algorithm settings. /// </param> /// <param name="keyIdentifier"> /// The key identifier to retrieve the encryption key. /// </param> public SymmetricDecryptStream( Stream stream, SymmetricDecryptionSettings settings, string?keyIdentifier = null) { Check.NotNull(stream, nameof(stream)); Check.NotNull(settings, nameof(settings)); _cryptoTransform = CreateCryptoTransform(settings, stream, keyIdentifier); _cryptoStream = new CryptoStream(stream, _cryptoTransform, CryptoStreamMode.Read); }
private static ICryptoTransform CreateCryptoTransform( SymmetricDecryptionSettings settings, Stream stream, string?keyIdentifier) { Check.NotNull(settings, nameof(settings)); Check.NotNull(stream, nameof(stream)); byte[]? encryptionKey = settings.KeyProvider != null ? settings.KeyProvider(keyIdentifier) : settings.Key; using var algorithm = SymmetricAlgorithmFactory.CreateSymmetricAlgorithm(settings, encryptionKey); if (settings.InitializationVector != null) { return(algorithm.CreateDecryptor()); } // Read the IV prepended to the message byte[] buffer = new byte[algorithm.IV.Length]; var totalReadCount = 0; while (totalReadCount < algorithm.IV.Length) { int readCount = stream.Read(buffer, totalReadCount, algorithm.IV.Length - totalReadCount); if (readCount == 0) { break; } totalReadCount += readCount; } algorithm.IV = buffer; return(algorithm.CreateDecryptor()); }