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;
                    }
                }
            }
        }
Пример #2
0
        public static async Task <ContainerHeader> ReadFromStream(Stream stream)
        {
            using (BinaryDataStream dataStream = new BinaryDataStream(stream, false))
            {
                await CheckPrefix(dataStream);

                ContainerHeader header = new ContainerHeader();
                header.Version = await dataStream.Read2BitNumber();

                if (header.Version != DefaultVersion)
                {
                    throw new InvalidOperationException($"Encryption file version {header.Version} is not supported.");
                }

                header.Reserved = await dataStream.Read4BitNumber();

                header.KeyType = (ContainerKeyType)await dataStream.Read4BitNumber();

                int encryptedKeySize = header.KeyType switch
                {
                    ContainerKeyType.Rsa2048 => 256,
                    ContainerKeyType.Rsa3072 => 384,
                    ContainerKeyType.Rsa4096 => 512,
                    _ => throw new NotSupportedException($"Not support key type {header.KeyType}")
                };

                header.EncryptedDataSize = await dataStream.Read8BitNumber();

                header.CertificateThumbprint = await dataStream.ReadConstatntString(40, Encoding.ASCII);

                header.EncryptedKey     = new byte[encryptedKeySize];
                header.InitializeVector = new byte[16];

                await dataStream.ReadAsync(header.EncryptedKey, 0, header.EncryptedKey.Length);

                await dataStream.ReadAsync(header.InitializeVector, 0, header.InitializeVector.Length);

                return(header);
            }
        }
        public async Task WriteRead4ByteNumber(uint value)
        {
            using MemoryStream ms         = new MemoryStream();
            using BinaryDataStream stream = new BinaryDataStream(ms);
            await stream.Write4BitNumber(value);

            await stream.FlushAsync();

            stream.Position = 0;

            uint readedValue = await stream.Read4BitNumber();

            Assert.AreEqual(value, readedValue);
        }