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); } } }
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)); } }
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."); } }
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); } } }
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)); } }
/// <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(); }
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()); } } }
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(); } }