Exemplo n.º 1
0
        public void StreamCryptography_FileEncrypt()
        {
            // Verify that we can encrypt one file to another and then decrypt it.

            var key           = Crypto.GenerateSymmetricKey(CryptoAlgorithm.AES, 256);
            var inputPath     = Path.GetTempFileName();
            var encryptedPath = Path.GetTempFileName();
            var decryptedPath = Path.GetTempFileName();

            byte[] data;
            byte[] buffer;

            data = new byte[16 * 1024];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = (byte)i;
            }

            try
            {
                using (var fs = new FileStream(inputPath, FileMode.Create, FileAccess.ReadWrite))
                {
                    fs.Write(data, 0, data.Length);
                }

                using (var encryptor = new StreamEncryptor(key))
                {
                    encryptor.Encrypt(inputPath, encryptedPath);
                }

                buffer = File.ReadAllBytes(encryptedPath);
                Assert.IsFalse(Helper.ArrayEquals(data, buffer));

                using (var decryptor = new StreamDecryptor(key))
                {
                    decryptor.Decrypt(encryptedPath, decryptedPath);
                }

                buffer = File.ReadAllBytes(decryptedPath);
                Assert.IsTrue(Helper.ArrayEquals(data, buffer));
            }
            finally
            {
                if (File.Exists(inputPath))
                {
                    File.Delete(inputPath);
                }

                if (File.Exists(encryptedPath))
                {
                    File.Delete(encryptedPath);
                }

                if (File.Exists(decryptedPath))
                {
                    File.Delete(decryptedPath);
                }
            }
        }
Exemplo n.º 2
0
        public void StreamCryptography_PartialStream()
        {
            // Verify that we can encrypt/decrypt a portion of a stream.

            var key       = Crypto.GenerateSymmetricKey(CryptoAlgorithm.AES, 256);
            var data      = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            var input     = new MemoryStream();
            var encrypted = new MemoryStream();
            var decrypted = new MemoryStream();

            byte[] buffer;

            input.Write(data, 0, data.Length);

            // Verify encryption.

            using (var encryptor = new StreamEncryptor(key))
            {
                encrypted.Write(new byte[] { 0 }, 0, 1);

                input.Position = 1;
                encryptor.Encrypt(input, encrypted, 8);

                encrypted.Write(new byte[] { 9 }, 0, 1);

                Assert.IsTrue(encrypted.Length > 2);
                encrypted.Position = 1;
                buffer             = new byte[8];
                encrypted.Read(buffer, 0, 8);
                Assert.IsFalse(Helper.ArrayEquals(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, buffer));
            }

            // Verify decryption.

            using (var decryptor = new StreamDecryptor(key))
            {
                buffer = new byte[] { 0 };

                encrypted.Position = 0;
                encrypted.Read(buffer, 0, 1);
                decrypted.Write(buffer, 0, 1);

                decrypted.Position = 1;
                decryptor.Decrypt(encrypted, decrypted, (int)(encrypted.Length - 2));

                buffer = new byte[] { 9 };
                encrypted.Read(buffer, 0, 1);
                decrypted.Write(buffer, 0, 1);

                decrypted.Position = 0;
                buffer             = new byte[(int)decrypted.Length];
                decrypted.Read(buffer, 0, buffer.Length);
                Assert.IsTrue(Helper.ArrayEquals(data, buffer));
            }
        }
Exemplo n.º 3
0
        private static StreamDecryptor CreateDecryptor(string algorithm, byte[] key, byte[] nonce)
        {
            switch (algorithm)
            {
            case "AES-SIV": return(StreamDecryptor.CreateAesCmacSivDecryptor(key, nonce));

            case "AES-PMAC-SIV": return(StreamDecryptor.CreateAesPmacSivDecryptor(key, nonce));

            default: throw new ArgumentException("Unknown algorithm.");
            }
        }
Exemplo n.º 4
0
        private static void StreamExample()
        {
            // Messages to encrypt.
            var messages = new List <string> {
                "Now that the party is jumping",
                "With the bass kicked in, the fingers are pumpin'",
                "Quick to the point, to the point no faking",
                "I'm cooking MC's like a pound of bacon"
            };

            // Create a 32-byte key.
            var key = Aead.GenerateKey256();

            // Create a 8-byte STREAM nonce (required).
            var nonce = StreamEncryptor.GenerateNonce();

            // Create STREAM encryptor and decryptor using the AES-CMAC-SIV
            // algorithm. They implement the IDisposable interface,
            // so it's best to create them inside using statement.
            using (var encryptor = StreamEncryptor.CreateAesCmacSivEncryptor(key, nonce))
                using (var decryptor = StreamDecryptor.CreateAesCmacSivDecryptor(key, nonce))
                {
                    for (int i = 0; i < messages.Count; ++i)
                    {
                        // Calculate whether the message is the last message to encrypt.
                        bool last = i == messages.Count - 1;

                        // Convert the message to byte array first.
                        var bytes = Encoding.UTF8.GetBytes(messages[i]);

                        // Encrypt the message.
                        var ciphertext = encryptor.Seal(bytes, null, last);

                        // Decrypt the message.
                        var message = decryptor.Open(ciphertext, null, last);

                        // Convert the message back to string.
                        var plaintext = Encoding.UTF8.GetString(bytes);

                        // Print the decrypted message to the standard output.
                        Console.WriteLine(plaintext);
                    }
                }
        }
Exemplo n.º 5
0
        public void StreamCryptography_EntireStream()
        {
            // Verify that we can encrypt an entire stream and the decrypt it.

            var key       = Crypto.GenerateSymmetricKey(CryptoAlgorithm.AES, 256);
            var data      = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            var input     = new MemoryStream();
            var encrypted = new MemoryStream();
            var decrypted = new MemoryStream();

            byte[] buffer;

            input.Write(data, 0, data.Length);

            // Verify encryption.

            using (var encryptor = new StreamEncryptor(key))
            {
                input.Position = 0;
                encryptor.Encrypt(input, encrypted);
                Assert.IsTrue(encrypted.Length > 0);
                encrypted.Position = 0;
                buffer             = new byte[(int)encrypted.Length];
                encrypted.Read(buffer, 0, buffer.Length);
                Assert.IsFalse(Helper.ArrayEquals(data, buffer));
            }

            // Verify decryption.

            using (var decryptor = new StreamDecryptor(key))
            {
                encrypted.Position = 0;
                decryptor.Decrypt(encrypted, decrypted);
                Assert.IsTrue(decrypted.Length > 0);
                decrypted.Position = 0;
                buffer             = new byte[(int)decrypted.Length];
                decrypted.Read(buffer, 0, buffer.Length);
                Assert.IsTrue(Helper.ArrayEquals(data, buffer));
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Streams a commited file back to a client on the ambient HTTP request, optionally decrypting it first.
        /// </summary>
        /// <param name="key">Pass as the encryption key if the file is to be decrypted before delivery or <c>null</c> if the file is to be delivered as is.</param>
        /// <param name="id">The file <see cref="Guid" />.</param>
        /// <param name="fileName">The name of the file to be used when setting the response's <b>Content-Disposition</b> header or just the file extension (including the leading period).</param>
        /// <exception cref="InvalidOperationException">Thrown if the method is not called within the processing context of a HTTP request.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="fileName" /> is <c>null</c>.</exception>
        public void StreamFile(SymmetricKey key, Guid id, string fileName)
        {
            var context = HttpContext.Current;

            if (context == null)
            {
                throw new InvalidOperationException(WebHelper.NoHttpContextMsg);
            }

            var response = context.Response;

            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }

            var fileExtension = Path.GetExtension(fileName);

            if (string.IsNullOrWhiteSpace(fileExtension))
            {
                fileExtension = ".";
            }

            if (!string.IsNullOrWhiteSpace(fileName))
            {
                WebHelper.SetResponseContentDisposition(fileName);
            }

            var mimeType = WebHelper.GetMimeMapping(fileName);

            if (mimeType != null)
            {
                response.ContentType = mimeType;
            }

            // Make sure the file actually exists.

            var cachedFile = GetFile(id, fileExtension, false);
            var fileInfo   = new FileInfo(cachedFile.Path);

            if (!fileInfo.Exists)
            {
                response.StatusCode        = 404;
                response.StatusDescription = "Not Found";

                response.End();
                return;
            }

            // If there's no key, we can simply let IIS stream the file directly.

            if (key == null)
            {
                response.StatusCode        = 200;
                response.StatusDescription = "OK";

                response.WriteFile(cachedFile.Path);
                response.End();
                return;
            }

            // We need to decrypt and stream the file.

            using (var encryptedStream = new FileStream(cachedFile.Path, FileMode.Open, FileAccess.Read))
            {
                using (var decryptor = new StreamDecryptor(key))
                {
                    decryptor.Decrypt(encryptedStream, response.OutputStream);
                }
            }

            response.End();
        }
Exemplo n.º 7
0
        public void WebTransferFile_UploadEncrypt()
        {
            // Test the file upload with encryption.

            WebTransferFile transferFile;
            Guid            id;

            byte[] block1 = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            byte[] block2 = new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
            byte[] block;

            ClearFolder();

            // Create a file

            id           = Guid.NewGuid();
            transferFile = new WebTransferFile(id, folder, new Uri("http://test.com"), ".pdf", true, true);
            Assert.AreEqual(id, transferFile.ID);
            Assert.IsTrue(transferFile.IsUploading);
            Assert.IsTrue(File.Exists(transferFile.Path + WebTransferCache.UploadExtension));
            Assert.AreEqual(new Uri(new Uri("http://test.com"), transferFile.ID.ToString("D") + ".pdf"), transferFile.Uri);

            // Append the first block

            transferFile.Append(block1);

            // Open an existing file

            transferFile = new WebTransferFile(id, folder, new Uri("http://test.com"), ".pdf", false, true);
            Assert.AreEqual(id, transferFile.ID);
            Assert.IsTrue(transferFile.IsUploading);
            Assert.IsTrue(File.Exists(transferFile.Path + WebTransferCache.UploadExtension));
            Assert.AreEqual(new Uri(new Uri("http://test.com"), transferFile.ID.ToString("D") + ".pdf"), transferFile.Uri);

            // Append the second block

            transferFile.Append(block2);

            // Complete the upload and verify the file contents.

            transferFile.Commit();
            Assert.AreEqual(id, transferFile.ID);
            Assert.IsFalse(transferFile.IsUploading);
            Assert.IsTrue(File.Exists(transferFile.Path));
            Assert.AreEqual(new Uri(new Uri("http://test.com"), transferFile.ID.ToString("D") + ".pdf"), transferFile.Uri);

            using (var stream = transferFile.GetStream())
            {
                block = stream.ReadBytes((int)stream.Length);
                CollectionAssert.AreEqual(Helper.Concat(block1, block2), block);
            }

            // Now encrypt the file and verify.

            var key = Crypto.GenerateSymmetricKey(CryptoAlgorithm.AES, 256);

            transferFile.Encrypt(key);

            using (var stream = transferFile.GetStream())
            {
                block = stream.ReadBytes((int)stream.Length);
                CollectionAssert.AreNotEqual(Helper.Concat(block1, block2), block); // Shouldn't be equal any more due to the encryption.
            }

            // Decrypt and verify.

            using (var stream = transferFile.GetStream())
            {
                using (var decryptor = new StreamDecryptor(key))
                {
                    var ms = new MemoryStream();

                    decryptor.Decrypt(stream, ms);
                    CollectionAssert.AreEqual(Helper.Concat(block1, block2), ms.ToArray());
                }
            }
        }
Exemplo n.º 8
0
        public void WebTransferCache_UploadEncrypt()
        {
            // Test file upload with encryption.

            WebTransferCache cache;
            WebTransferFile  transferFile;
            Guid             id;

            byte[] block1 = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            byte[] block2 = new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
            byte[] block;
            long   pos;

            ClearFolder();

            cache = new WebTransferCache(new Uri("http://test.com"), folder, "", TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));
            cache.Start();

            try
            {
                // Create a file

                transferFile = cache.GetUploadFile(Guid.Empty, ".pdf");
                id           = transferFile.ID;
                Assert.AreNotEqual(Guid.Empty, transferFile.ID);
                Assert.IsTrue(transferFile.IsUploading);
                Assert.IsTrue(File.Exists(transferFile.Path + WebTransferCache.UploadExtension));
                Assert.AreEqual(new Uri(new Uri("http://test.com/" + cache.HashIDToSubFolder(transferFile.ID)), transferFile.ID.ToString("D") + ".pdf"), transferFile.Uri);

                // Append the first block

                pos = 0;
                transferFile.Append(pos, block1);

                // Append it again to simulate a duplicate

                transferFile.Append(pos, block1);
                pos += block1.Length;

                // Open an existing file

                transferFile = cache.GetUploadFile(id, ".pdf");
                Assert.AreEqual(id, transferFile.ID);
                Assert.IsTrue(transferFile.IsUploading);
                Assert.IsTrue(File.Exists(transferFile.Path + WebTransferCache.UploadExtension));
                Assert.AreEqual(new Uri(new Uri("http://test.com/" + cache.HashIDToSubFolder(transferFile.ID)), transferFile.ID.ToString("D") + ".pdf"), transferFile.Uri);

                // Append the second block

                transferFile.Append(pos, block2);

                // Complete the upload and verify the file contents.

                transferFile.Commit(MD5Hasher.Compute(Helper.Concat(block1, block2)));
                Assert.AreEqual(id, transferFile.ID);
                Assert.IsFalse(transferFile.IsUploading);
                Assert.IsTrue(File.Exists(transferFile.Path));
                Assert.AreEqual(new Uri(new Uri("http://test.com/" + cache.HashIDToSubFolder(transferFile.ID)), transferFile.ID.ToString("D") + ".pdf"), transferFile.Uri);

                using (var stream = transferFile.GetStream())
                {
                    block = stream.ReadBytes((int)stream.Length);
                    CollectionAssert.AreEqual(Helper.Concat(block1, block2), block);
                }

                // Now encrypt the file and verify.

                var key = Crypto.GenerateSymmetricKey(CryptoAlgorithm.AES, 256);

                cache.EncryptFile(key, id, ".pdf");

                using (var stream = transferFile.GetStream())
                {
                    block = stream.ReadBytes((int)stream.Length);
                    CollectionAssert.AreNotEqual(Helper.Concat(block1, block2), block); // Shouldn't be equal any more due to the encryption.
                }

                // Decrypt and verify.

                using (var stream = transferFile.GetStream())
                {
                    using (var decryptor = new StreamDecryptor(key))
                    {
                        var ms = new MemoryStream();

                        decryptor.Decrypt(stream, ms);
                        CollectionAssert.AreEqual(Helper.Concat(block1, block2), ms.ToArray());
                    }
                }
            }
            finally
            {
                cache.Stop();
            }
        }