コード例 #1
0
ファイル: EncryptedFileHeader.cs プロジェクト: yvanam/SyncPro
        /// <summary>
        /// Read the encrypted file header information from a stream
        /// </summary>
        /// <param name="stream">The stream to read</param>
        /// <returns>The encrypted header object</returns>
        public static EncryptedFileHeader ReadFromStream(Stream stream)
        {
            Pre.ThrowIfArgumentNull(stream, nameof(stream));

            // Read the entire header from the stream
            byte[] buffer = stream.ReadByteArray(HeaderSize);

            // Verify the header's checksum
            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
            {
                byte[] computedHash = sha1.ComputeHash(buffer, 0, HeaderSize - ChecksumSize);
                byte[] headerHash   = BufferUtil.CopyBytes(buffer, buffer.Length - ChecksumSize, ChecksumSize);

                if (!NativeMethods.ByteArrayEquals(computedHash, headerHash))
                {
                    // TODO: Replace with a better exception
                    throw new Exception("The header checksum failed");
                }
            }

            // Create a new stream for reading the header data. This will make it easier to process the
            // fields in the header and will avoid having to reposition the original stream.
            using (MemoryStream headerStream = new MemoryStream(buffer))
            {
                EncryptedFileHeader header = new EncryptedFileHeader();

                int encryptedKeyLength = headerStream.ReadInt32();

                // Ensure the key is not longer than the buffer
                Pre.Assert(encryptedKeyLength < HeaderSize, "encryptedKeyLength < HeaderSize");

                // Read the encrypted key field.
                header.EncryptedKey = headerStream.ReadByteArray(encryptedKeyLength);

                // Read the IV length. This should be 16 bytes (asserted below).
                int ivLength = headerStream.ReadInt32();

                Pre.Assert(ivLength == IVStorageSize, "ivLength == ivStorageSize");

                // Read the initialization vector
                header.IV = headerStream.ReadByteArray(ivLength);

                // Read the file sizes, thumbprint, and padding
                header.OriginalFileLength    = headerStream.ReadInt64();
                header.EncryptedFileLength   = headerStream.ReadInt64();
                header.CertificateThumbprint = headerStream.ReadByteArray(CertificateThumbprintSize);
                header.PaddingLength         = headerStream.ReadInt16();

                return(header);
            }
        }
コード例 #2
0
ファイル: EncryptionManager.cs プロジェクト: yvanam/SyncPro
        private void ReadFirstEncryptedBlock(byte[] inputBuffer, ref int offset, ref int count)
        {
            // Create a temporary stream for reading the input buffer. This will make it easier to read the
            // input buffer and preserve the read position in the buffer.
            using (MemoryStream inputBufferStream = new MemoryStream(inputBuffer, offset, count))
            {
                EncryptedFileHeader header = EncryptedFileHeader.ReadFromStream(inputBufferStream);

                // Decrypt the key.
                byte[] key = this.rsa.Decrypt(header.EncryptedKey, false);

                // Create the decrypter used to decrypt the file
                this.cryptoTransform = this.aes.CreateDecryptor(key, header.IV);

                // Update the count and offset based on the size read for the header since these will
                // be used below to decrypt the buffer.
                count -= (int)inputBufferStream.Position - offset;
                offset = (int)inputBufferStream.Position;
            }

            this.firstBlockTransformed = true;
        }
コード例 #3
0
ファイル: EncryptionManager.cs プロジェクト: yvanam/SyncPro
        private void WriteFirstEncryptedBlock(MemoryStream bufferedOutputStream)
        {
            // Create the encryptor that will be used to transform the data. This will use the key and IV
            // that were generated when the aes object was created, and will only be used for this stream.
            this.cryptoTransform = this.aes.CreateEncryptor();

            RSAPKCS1KeyExchangeFormatter keyFormatter = new RSAPKCS1KeyExchangeFormatter(this.rsa);

            byte[] keyEncrypted = keyFormatter.CreateKeyExchange(this.aes.Key, this.aes.GetType());

            EncryptedFileHeader header = new EncryptedFileHeader
            {
                EncryptedKey          = keyEncrypted,
                IV                    = this.aes.IV,
                CertificateThumbprint = AdapterBase.HexToBytes(this.encryptionCertificate.Thumbprint)
            };

            short padding;

            if (this.Mode == EncryptionMode.Encrypt)
            {
                header.OriginalFileLength  = this.sourceFileSize;
                header.EncryptedFileLength = CalculateEncryptedFileSize(this.sourceFileSize, out padding);
                header.PaddingLength       = padding;
            }
            else
            {
                header.EncryptedFileLength = this.sourceFileSize;
                header.OriginalFileLength  = CalculateDecryptedFileSize(this.sourceFileSize, out padding);
                header.PaddingLength       = padding;
            }

            header.WriteToStream(bufferedOutputStream);

            this.firstBlockTransformed = true;
        }