public ContainerWriter(Stream writeStream, string fileName, X509Certificate2 certificate)
        {
            this.writeStream = writeStream ?? throw new ArgumentNullException(nameof(writeStream));
            this.fileName    = fileName ?? throw new ArgumentNullException(nameof(writeStream));
            FileNameHelper.CheckFileName(fileName, nameof(fileName));

            this.aes           = new AesManaged();
            this.aes.Mode      = CipherMode.CBC;
            this.aes.Padding   = PaddingMode.PKCS7;
            this.aes.KeySize   = 256;
            this.aes.BlockSize = 128;

            this.randomSource = new Random(Guid.NewGuid().GetHashCode());

            this.aes.GenerateKey();
            this.aes.GenerateIV();

            this.header = new ContainerHeader();
            this.header.CertificateThumbprint = certificate.Thumbprint;
            this.header.EncryptedDataSize     = 0L;
            this.header.KeyType          = this.GetKeyType(certificate.GetRSAPublicKey());
            this.header.EncryptedKey     = certificate.GetRSAPublicKey().Encrypt(this.aes.Key, RSAEncryptionPadding.Pkcs1); //RSA Padding
            this.header.InitializeVector = this.aes.IV;

            this.encryptor            = this.aes.CreateEncryptor();
            this.headerWrited         = false;
            this.AdditionalPadingSize = (uint)this.randomSource.Next(512, 2048);
        }
        public async Task <string> ReadFileName()
        {
            if (this.fileName != null)
            {
                return(this.fileName);
            }

            ContainerHeader header = await ContainerHeader.ReadFromStream(this.readerStream);

            byte[]? aesKey = null;
            try
            {
                aesKey = await this.cryptoAccessor.AsymetricDecrypt(header.CertificateThumbprint, header.EncryptedKey, RSAEncryptionPadding.Pkcs1);  //RSA Padding

                this.aesDecryptor = this.aes.CreateDecryptor(aesKey, header.InitializeVector);
                this.cryptoStream = new CryptoStream(this.readerStream, this.aesDecryptor, CryptoStreamMode.Read);

                using (BinaryDataStream bds = new BinaryDataStream(this.cryptoStream, false))
                {
                    //TODO: Optimalization
                    for (uint i = 0; i < 16; i++)
                    {
                        bds.ReadByte();
                    }

                    uint randomDataSize = await bds.Read4BitNumber();

                    uint stringLen = await bds.Read4BitNumber();

                    //TODO: Optimalization
                    for (uint i = 0; i < randomDataSize; i++)
                    {
                        bds.ReadByte();
                    }

                    string fileName = await bds.ReadConstatntString((int)stringLen, Encoding.UTF8);

                    FileNameHelper.CheckFileName(fileName, nameof(fileName));
                    this.fileName = fileName;

                    return(fileName);
                }
            }
            finally
            {
                if (aesKey != null)
                {
                    for (int i = 0; i < aesKey.Length; i++)
                    {
                        aesKey[i] = 0x00;
                        aesKey[i] = 0xFF;
                    }
                }
            }
        }
 public void TestCheckFileName()
 {
     Assert.True(FileNameHelper.CheckFileName("myDirectory"));
     Assert.True(FileNameHelper.CheckFileName("myTextFile.txt"));
     Assert.False(FileNameHelper.CheckFileName(""));
     Assert.False(FileNameHelper.CheckFileName(null));
     Assert.False(FileNameHelper.CheckFileName("t_<_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_>_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_:_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_\"_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_/_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_\\_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_|_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_?_.txt"));
     Assert.False(FileNameHelper.CheckFileName("t_*_.txt"));
 }