public void CloudQueueAddUpdateEncryptedMessage() { // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); RsaKey rsaKey = new RsaKey("asymencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); resolver.Add(rsaKey); DoCloudQueueAddUpdateEncryptedMessage(aesKey, resolver); DoCloudQueueAddUpdateEncryptedMessage(rsaKey, resolver); }
public void CloudQueueAddUpdateEncryptedMessage() { // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); RsaKey rsaKey = new RsaKey("asymencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); resolver.Add(rsaKey); DoCloudQueueAddUpdateEncryptedMessage(aesKey, resolver); DoCloudQueueAddUpdateEncryptedMessage(rsaKey, resolver); }
private void DoInsertPOCOEntityEncryptionWithAttributesAndResolver(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Insert Entity EncryptedBaseEntity ent = new EncryptedBaseEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() + format }; ent.Populate(); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions insertOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), EncryptionResolver = (pk, rk, propName) => { if (propName == "B") { return true; } return false; } }; // Since we have specified attributes and resolver, properties A, B and foo will be encrypted. currentTable.Execute(TableOperation.Insert(ent), insertOptions, null); // Retrieve entity without decryption and confirm that all 3 properties were encrypted. // No need for an encryption resolver while retrieving the entity. TableOperation operation = TableOperation.Retrieve<EncryptedBaseEntity>(ent.PartitionKey, ent.RowKey); Assert.IsFalse(operation.IsTableEntity); TableResult result = currentTable.Execute(operation, null, null); EncryptedBaseEntity retrievedEntity = result.Result as EncryptedBaseEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); // Since we store encrypted properties as byte arrays, if a POCO entity is being read as-is, odata will not assign the binary // values to strings. In JSON no metadata, the service does not return the types and the client lib does the parsing and reads the // base64 encoded string as-is. if (format == TablePayloadFormat.JsonNoMetadata) { Assert.IsNotNull(retrievedEntity.foo); Assert.IsNotNull(retrievedEntity.A); Assert.IsNotNull(retrievedEntity.B); Assert.AreEqual(ent.foo.GetType(), retrievedEntity.foo.GetType()); Assert.AreEqual(ent.A.GetType(), retrievedEntity.A.GetType()); Assert.AreEqual(ent.B.GetType(), retrievedEntity.B.GetType()); } else { Assert.IsNull(retrievedEntity.foo); Assert.IsNull(retrievedEntity.A); Assert.IsNull(retrievedEntity.B); } // Retrieve entity without decryption and confirm that all 3 properties were encrypted. // No need for an encryption resolver while retrieving the entity. operation = TableOperation.Retrieve<DynamicTableEntity>(ent.PartitionKey, ent.RowKey); Assert.IsFalse(operation.IsTableEntity); result = currentTable.Execute(operation, null, null); DynamicTableEntity retrievedDynamicEntity = result.Result as DynamicTableEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(ent.PartitionKey, retrievedDynamicEntity.PartitionKey); Assert.AreEqual(ent.RowKey, retrievedDynamicEntity.RowKey); if (format == TablePayloadFormat.JsonNoMetadata) { Assert.AreEqual(EdmType.String, retrievedDynamicEntity.Properties["foo"].PropertyType); Assert.AreEqual(EdmType.String, retrievedDynamicEntity.Properties["A"].PropertyType); Assert.AreEqual(EdmType.String, retrievedDynamicEntity.Properties["B"].PropertyType); } else { Assert.AreEqual(EdmType.Binary, retrievedDynamicEntity.Properties["foo"].PropertyType); Assert.AreEqual(EdmType.Binary, retrievedDynamicEntity.Properties["A"].PropertyType); Assert.AreEqual(EdmType.Binary, retrievedDynamicEntity.Properties["B"].PropertyType); } // Retrieve entity and decrypt. TableRequestOptions retrieveOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; operation = TableOperation.Retrieve<EncryptedBaseEntity>(ent.PartitionKey, ent.RowKey); Assert.IsFalse(operation.IsTableEntity); result = currentTable.Execute(operation, retrieveOptions, null); retrievedEntity = result.Result as EncryptedBaseEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); retrievedEntity.Validate(); }
private void DoInsertPOCOEntityEncryptionWithAttributes(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Insert Entity EncryptedBaseEntity ent = new EncryptedBaseEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() + format}; ent.Populate(); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions insertOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null) }; currentTable.Execute(TableOperation.Insert(ent), insertOptions, null); // Retrieve Entity // No need for an encryption resolver while retrieving the entity. TableRequestOptions retrieveOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; TableOperation operation = TableOperation.Retrieve<EncryptedBaseEntity>(ent.PartitionKey, ent.RowKey); Assert.IsFalse(operation.IsTableEntity); TableResult result = currentTable.Execute(operation, retrieveOptions, null); EncryptedBaseEntity retrievedEntity = result.Result as EncryptedBaseEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); retrievedEntity.Validate(); }
public void TableQueryEncryptionMixedMode() { // Insert Entity EncryptedBaseEntity ent1 = new EncryptedBaseEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent1.Populate(); EncryptedBaseEntity ent2 = new EncryptedBaseEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent2.Populate(); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null) }; // Insert an encrypted entity. currentTable.Execute(TableOperation.Insert(ent1), options, null); // Insert a non-encrypted entity. currentTable.Execute(TableOperation.Insert(ent2), null, null); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; // Set RequireEncryption to false and query. This will succeed. options.RequireEncryption = false; TableQuery<EncryptedBaseEntity> query = new TableQuery<EncryptedBaseEntity>(); currentTable.ExecuteQuery(query, options).ToList(); // Set RequireEncryption to true and query. This will fail because it can't find the metadata for the second enctity on the server. options.RequireEncryption = true; TestHelper.ExpectedException<StorageException>( () => currentTable.ExecuteQuery(query, options).ToList(), "All entities retrieved should be encrypted when RequireEncryption is set to true."); }
private void DoInsertDynamicTableEntityEncryptionSync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Insert Entity DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent.Properties.Add("foo2", new EntityProperty(string.Empty)); ent.Properties.Add("foo", new EntityProperty("bar")); ent.Properties.Add("fooint", new EntityProperty(1234)); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), EncryptionResolver = (pk, rk, propName) => { if (propName == "foo" || propName == "foo2") { return true; } return false; } }; currentTable.Execute(TableOperation.Insert(ent), options, null); // Retrieve Entity TableRequestOptions retrieveOptions = new TableRequestOptions() { PropertyResolver = (pk, rk, propName, propValue) => { if (propName == "fooint") { return EdmType.Int32; } return (EdmType)0; }, EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey); Assert.IsFalse(operation.IsTableEntity); TableResult result = currentTable.Execute(operation, retrieveOptions, null); DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); Assert.AreEqual(ent.Properties["fooint"], retrievedEntity.Properties["fooint"]); Assert.AreEqual(ent.Properties["fooint"].Int32Value, retrievedEntity.Properties["fooint"].Int32Value); }
private void DoTableBatchInsertOrReplaceEncryption(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), EncryptionResolver = (pk, rk, propName) => { if (propName == "A" || propName == "B") { return true; } return false; } }; // Insert Or Replace with no pre-existing entity DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo" + format.ToString()); insertOrReplaceEntity.Properties.Add("A", new EntityProperty("a")); TableBatchOperation batch = new TableBatchOperation(); batch.InsertOrReplace(insertOrReplaceEntity); currentTable.ExecuteBatch(batch, options); // Retrieve Entity & Verify Contents // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions retrieveOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey), retrieveOptions); DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); replaceEntity.Properties.Add("B", new EntityProperty("b")); TableBatchOperation batch2 = new TableBatchOperation(); batch2.InsertOrReplace(replaceEntity); currentTable.ExecuteBatch(batch2, options); // Retrieve Entity & Verify Contents result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey), retrieveOptions); retrievedEntity = result.Result as DynamicTableEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(1, retrievedEntity.Properties.Count); Assert.AreEqual(replaceEntity.Properties["B"], retrievedEntity.Properties["B"]); }
private void DoTableQueryDTEProjectionEncryption(TablePayloadFormat format, SymmetricKey aesKey) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; TableQuery query = new TableQuery().Select(new List<string>() { "A" }); foreach (DynamicTableEntity ent in currentTable.ExecuteQuery(query, options)) { Assert.IsNotNull(ent.PartitionKey); Assert.IsNotNull(ent.RowKey); Assert.IsNotNull(ent.Timestamp); Assert.IsTrue(ent.Properties["A"].StringValue == "a" || ent.Properties["A"].StringValue == String.Empty); } }
public void CloudBlobEncryptionWithFile() { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); int size = 5 * 1024 * 1024; byte[] buffer = GetRandomBuffer(size); CloudBlockBlob blob = container.GetBlockBlobReference("blockblob"); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; string inputFileName = Path.GetTempFileName(); string outputFileName = Path.GetTempFileName(); using (FileStream file = new FileStream(inputFileName, FileMode.Create, FileAccess.Write)) { file.Write(buffer, 0, buffer.Length); } // Upload the encrypted contents to the blob. blob.UploadFromFile(inputFileName, FileMode.Open, null, uploadOptions, null); // Download the encrypted blob. // Create the decryption policy to be used for download. There is no need to specify the // key when the policy is only going to be used for downloads. Resolver is sufficient. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the decryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy }; // Download and decrypt the encrypted contents from the blob. blob.DownloadToFile(outputFileName, FileMode.Create, null, downloadOptions, null); // Compare that the decrypted contents match the input data. using (FileStream inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), outputFileStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) { TestHelper.AssertStreamsAreEqual(inputFileStream, outputFileStream); } } finally { container.DeleteIfExists(); } }
private static void DoCloudBlobEncryptionAPM(BlobType type, bool partial) { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); int size = 5 * 1024 * 1024; byte[] buffer = GetRandomBuffer(size); if (partial) { size = 2 * 1024 * 1024; } ICloudBlob blob = GetCloudBlobReference(type, container); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; MemoryStream stream; // Upload the encrypted contents to the blob. using (stream = new MemoryStream(buffer)) { using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { ICancellableAsyncResult result = blob.BeginUploadFromStream( stream, size, null, uploadOptions, null, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blob.EndUploadFromStream(result); } // Ensure that the user stream is open. Assert.IsTrue(stream.CanSeek); } // Download the encrypted blob. // Create the decryption policy to be used for download. There is no need to specify the encryption mode // and the key wrapper when the policy is only going to be used for downloads. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the decryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy }; // Download and decrypt the encrypted contents from the blob. MemoryStream outputStream = new MemoryStream(); using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { ICancellableAsyncResult result = blob.BeginDownloadToStream(outputStream, null, downloadOptions, null, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blob.EndDownloadToStream(result); } // Ensure that the user stream is open. outputStream.Seek(0, SeekOrigin.Begin); // Compare that the decrypted contents match the input data. byte[] outputArray = outputStream.ToArray(); TestHelper.AssertBuffersAreEqualUptoIndex(outputArray, buffer, size - 1); } finally { container.DeleteIfExists(); } }
private void DoCloudBlobEncryptionWithStrictMode(BlobType type) { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); int size = 5 * 1024 * 1024; byte[] buffer = GetRandomBuffer(size); ICloudBlob blob; if (type == BlobType.BlockBlob) { blob = container.GetBlockBlobReference("blob1"); } else { blob = container.GetPageBlobReference("blob1"); } // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; // Set RequireEncryption flag to true. uploadOptions.RequireEncryption = true; // Upload an encrypted blob with the policy set. MemoryStream stream = new MemoryStream(buffer); blob.UploadFromStream(stream, size, null, uploadOptions, null); // Upload the blob when RequireEncryption is true and no policy is set. This should throw an error. uploadOptions.EncryptionPolicy = null; stream = new MemoryStream(buffer); TestHelper.ExpectedException<InvalidOperationException>( () => blob.UploadFromStream(stream, size, null, uploadOptions, null), "Not specifying a policy when RequireEnryption is set to true should throw."); // Create the encryption policy to be used for download. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the encryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy }; // Set RequireEncryption flag to true. downloadOptions.RequireEncryption = true; // Download the encrypted blob. MemoryStream outputStream = new MemoryStream(); blob.DownloadToStream(outputStream, null, downloadOptions, null); blob.Metadata.Clear(); // Upload a plain text blob. stream = new MemoryStream(buffer); blob.UploadFromStream(stream, size); // Try to download an encrypted blob with RequireEncryption set to true. This should throw. outputStream = new MemoryStream(); TestHelper.ExpectedException<StorageException>( () => blob.DownloadToStream(outputStream, null, downloadOptions, null), "Downloading with RequireEncryption set to true and no metadata on the service should fail."); // Set RequireEncryption to false and download. downloadOptions.RequireEncryption = false; blob.DownloadToStream(outputStream, null, downloadOptions, null); } finally { container.DeleteIfExists(); } }
private void CountOperationsHelper(int size, int targetUploadOperations, bool streamSeekable, bool isAPM, BlobRequestOptions options) { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); byte[] buffer = GetRandomBuffer(size); CloudBlockBlob blob = container.GetBlockBlobReference("blockblob"); blob.StreamWriteSizeInBytes = (int)(4 * Constants.MB); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. options.EncryptionPolicy = uploadPolicy; OperationContext opContext = new OperationContext(); int uploadCount = 0; opContext.SendingRequest += (sender, e) => uploadCount++; using (MemoryStream stream = streamSeekable ? new MemoryStream(buffer) : new NonSeekableMemoryStream(buffer)) { if (isAPM) { using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { blob.EndUploadFromStream(blob.BeginUploadFromStream( stream, size, null, options, opContext, ar => waitHandle.Set(), null)); } } else { blob.UploadFromStream(stream, size, null, options, opContext); } // Ensure that the user stream is open if it's seekable. if (streamSeekable) { Assert.IsTrue(stream.CanSeek); } } // Download the encrypted blob. // Create the decryption policy to be used for download. There is no need to specify the // key when the policy is only going to be used for downloads. Resolver is sufficient. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the decryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy }; // Download and decrypt the encrypted contents from the blob. MemoryStream outputStream = new MemoryStream(); blob.DownloadToStream(outputStream, null, downloadOptions, null); // Ensure that the user stream is open. outputStream.Seek(0, SeekOrigin.Begin); // Compare that the decrypted contents match the input data. byte[] outputArray = outputStream.ToArray(); TestHelper.AssertBuffersAreEqualUptoIndex(outputArray, buffer, size - 1); Assert.AreEqual(targetUploadOperations, uploadCount, "Incorrect number of operations in encrypted blob upload."); } finally { container.DeleteIfExists(); } }
public void CloudBlobEncryptionOpenWriteStreamAPMWithAccessCondition() { CloudBlobContainer container = GetRandomContainerReference(); try { int size = (int)(1 * Constants.MB); container.Create(); byte[] buffer = GetRandomBuffer(size); CloudBlockBlob blob = container.GetBlockBlobReference("blockblob"); blob.StreamWriteSizeInBytes = (int)(4 * Constants.MB); blob.UploadText("Sample initial text"); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy, RequireEncryption = true }; AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); using (MemoryStream stream = new NonSeekableMemoryStream(buffer)) { using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { blob.EndUploadFromStream(blob.BeginUploadFromStream( stream, size, accessCondition, uploadOptions, null, ar => waitHandle.Set(), null)); } } // Download the encrypted blob. // Create the decryption policy to be used for download. There is no need to specify the // key when the policy is only going to be used for downloads. Resolver is sufficient. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the decryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy, RequireEncryption = true }; // Download and decrypt the encrypted contents from the blob. MemoryStream outputStream = new MemoryStream(); blob.DownloadToStream(outputStream, null, downloadOptions, null); // Ensure that the user stream is open. outputStream.Seek(0, SeekOrigin.Begin); // Compare that the decrypted contents match the input data. byte[] outputArray = outputStream.ToArray(); TestHelper.AssertBuffersAreEqualUptoIndex(outputArray, buffer, size - 1); } finally { container.DeleteIfExists(); } }
public void CloudQueueMessageEncryptionWithStrictMode() { // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); CloudQueueClient client = GenerateCloudQueueClient(); string name = GenerateNewQueueName(); CloudQueue queue = client.GetQueueReference(name); try { queue.CreateIfNotExists(); string messageStr = Guid.NewGuid().ToString(); CloudQueueMessage message = new CloudQueueMessage(messageStr); QueueEncryptionPolicy policy = new QueueEncryptionPolicy(aesKey, null); // Add message with policy. QueueRequestOptions createOptions = new QueueRequestOptions() { EncryptionPolicy = policy }; createOptions.RequireEncryption = true; queue.AddMessage(message, null, null, createOptions, null); // Set policy to null and add message while RequireEncryption flag is still set to true. This should throw. createOptions.EncryptionPolicy = null; TestHelper.ExpectedException <InvalidOperationException>( () => queue.AddMessage(message, null, null, createOptions, null), "Not specifying a policy when RequireEnryption is set to true should throw."); // Retrieve message QueueEncryptionPolicy retrPolicy = new QueueEncryptionPolicy(null, resolver); QueueRequestOptions retrieveOptions = new QueueRequestOptions() { EncryptionPolicy = retrPolicy }; retrieveOptions.RequireEncryption = true; CloudQueueMessage retrMessage = queue.GetMessage(null, retrieveOptions, null); // Update message with plain text. string updatedMessage = Guid.NewGuid().ToString("N"); retrMessage.SetMessageContent(updatedMessage); queue.UpdateMessage(retrMessage, TimeSpan.FromSeconds(0), MessageUpdateFields.Content | MessageUpdateFields.Visibility); // Retrieve updated message with RequireEncryption flag but no metadata on the service. This should throw. TestHelper.ExpectedException <StorageException>( () => queue.GetMessage(null, retrieveOptions, null), "Retrieving with RequireEncryption set to true and no metadata on the service should fail."); // Set RequireEncryption to false and retrieve. retrieveOptions.RequireEncryption = false; queue.GetMessage(null, retrieveOptions, null); } finally { queue.DeleteIfExists(); } }
private void DoTableQueryPOCOProjectionEncryption(TablePayloadFormat format, SymmetricKey aesKey) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; TableQuery<EncryptedBaseEntity> query = new TableQuery<EncryptedBaseEntity>().Select(new List<string>() { "A", "C" }); foreach (EncryptedBaseEntity ent in currentTable.ExecuteQuery(query, options)) { Assert.IsNotNull(ent.PartitionKey); Assert.IsNotNull(ent.RowKey); Assert.IsNotNull(ent.Timestamp); Assert.AreEqual(ent.A, "a"); Assert.IsNull(ent.B); Assert.AreEqual(ent.C, "c"); Assert.IsNull(ent.D); Assert.AreEqual(ent.E, 0); } }
public void CloudBlobEncryptionWithByteArray() { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); int size = 5 * 1024 * 1024; byte[] buffer = GetRandomBuffer(size); byte[] outputBuffer = new byte[size]; CloudBlockBlob blob = container.GetBlockBlobReference("blockblob"); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; // Upload the encrypted contents to the blob. blob.UploadFromByteArray(buffer, 0, buffer.Length, null, uploadOptions, null); // Download the encrypted blob. // Create the decryption policy to be used for download. There is no need to specify the // key when the policy is only going to be used for downloads. Resolver is sufficient. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the decryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy }; // Download and decrypt the encrypted contents from the blob. blob.DownloadToByteArray(outputBuffer, 0, null, downloadOptions, null); // Compare that the decrypted contents match the input data. TestHelper.AssertBuffersAreEqual(buffer, outputBuffer); } finally { container.DeleteIfExists(); } }
public void TableQueryProjectionEncryptionNoSelect() { // Insert Entity EncryptedBaseEntity ent1 = new EncryptedBaseEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent1.Populate(); EncryptedBaseEntity ent2 = new EncryptedBaseEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent2.Populate(); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null) }; currentTable.Execute(TableOperation.Insert(ent1), options, null); currentTable.Execute(TableOperation.Insert(ent2), options, null); tableClient.DefaultRequestOptions.PayloadFormat = TablePayloadFormat.Json; // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableEncryptionPolicy encryptionPolicy = new TableEncryptionPolicy(null, resolver); IEnumerable<EncryptedBaseEntity> entities = null; CloudTableClient encryptingTableClient = new CloudTableClient(this.tableClient.StorageUri, this.tableClient.Credentials); encryptingTableClient.DefaultRequestOptions.EncryptionPolicy = encryptionPolicy; encryptingTableClient.DefaultRequestOptions.RequireEncryption = true; entities = encryptingTableClient.GetTableReference(currentTable.Name).CreateQuery<EncryptedBaseEntity>().Select(ent => ent); foreach (EncryptedBaseEntity ent in entities) { ent.Validate(); } }
public void CloudBlobEncryptionWithText() { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); string data = "String data"; CloudBlockBlob blob = container.GetBlockBlobReference("blockblob"); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; // Upload the encrypted contents to the blob. blob.UploadText(data, null, null, uploadOptions, null); // Download the encrypted blob. // Create the decryption policy to be used for download. There is no need to specify the // key when the policy is only going to be used for downloads. Resolver is sufficient. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the decryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy }; // Download and decrypt the encrypted contents from the blob. string outputData = blob.DownloadText(null, null, downloadOptions, null); // Compare that the decrypted contents match the input data. Assert.AreEqual(data, outputData); } finally { container.DeleteIfExists(); } }
public void TableEncryptionValidateSwappingPropertiesThrows() { // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), EncryptionResolver = (pk, rk, propName) => { if (propName == "Prop1") { return true; } return false; } }; // Insert Entities DynamicTableEntity baseEntity1 = new DynamicTableEntity("test1", "foo1"); baseEntity1.Properties.Add("Prop1", new EntityProperty("Value1")); currentTable.Execute(TableOperation.Insert(baseEntity1), options); DynamicTableEntity baseEntity2 = new DynamicTableEntity("test1", "foo2"); baseEntity2.Properties.Add("Prop1", new EntityProperty("Value2")); currentTable.Execute(TableOperation.Insert(baseEntity2), options); // Retrieve entity1 (Do not set encryption policy) TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity1.PartitionKey, baseEntity1.RowKey)); DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; // Replace entity2 with encrypted entity1's properties (Do not set encryption policy). DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity2.PartitionKey, baseEntity2.RowKey) { ETag = baseEntity2.ETag }; replaceEntity.Properties = retrievedEntity.Properties; currentTable.Execute(TableOperation.Replace(replaceEntity)); // Try to retrieve entity2 // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions retrieveOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; try { result = currentTable.Execute(TableOperation.Retrieve(baseEntity2.PartitionKey, baseEntity2.RowKey), retrieveOptions); Assert.Fail(); } catch (StorageException ex) { Assert.IsInstanceOfType(ex.InnerException, typeof(CryptographicException)); } }
public void CloudBlockBlobEncryptionValidateWrappers() { // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); RsaKey rsaKey = new RsaKey("asymencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); resolver.Add(rsaKey); DoCloudBlockBlobEncryptionValidateWrappers(aesKey, resolver); DoCloudBlockBlobEncryptionValidateWrappers(rsaKey, resolver); }
private void DoTableBatchRetrieveEncryptedEntitySync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), EncryptionResolver = (pk, rk, propName) => { if (propName == "A" || propName == "B") { return true; } return false; } }; // Add insert DynamicTableEntity sendEnt = GenerateRandomEntity(Guid.NewGuid().ToString()); // generate a set of properties for all supported Types sendEnt.Properties = new ComplexEntity().WriteEntity(null); sendEnt.Properties.Add("foo", new EntityProperty("bar")); TableBatchOperation batch = new TableBatchOperation(); batch.Retrieve<DynamicTableEntity>(sendEnt.PartitionKey, sendEnt.RowKey); // not found IList<TableResult> results = currentTable.ExecuteBatch(batch, options); Assert.AreEqual(results.Count, 1); Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); Assert.IsNull(results.First().Result); Assert.IsNull(results.First().Etag); // insert entity currentTable.Execute(TableOperation.Insert(sendEnt), options); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions retrieveOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) }; // Success results = currentTable.ExecuteBatch(batch, retrieveOptions); Assert.AreEqual(results.Count, 1); Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); DynamicTableEntity retrievedEntity = results.First().Result as DynamicTableEntity; // Validate entity Assert.AreEqual(sendEnt["foo"], retrievedEntity["foo"]); }
private void DoCloudBlobEncryption(BlobType type, bool partial) { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); int size = 5 * 1024 * 1024; byte[] buffer = GetRandomBuffer(size); if (partial) { size = 2 * 1024 * 1024; } ICloudBlob blob; if (type == BlobType.BlockBlob) { blob = container.GetBlockBlobReference("blockblob"); } else if (type == BlobType.PageBlob) { blob = container.GetPageBlobReference("pageblob"); } else { blob = container.GetAppendBlobReference("appendblob"); } // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; MemoryStream stream; // Upload the encrypted contents to the blob. using (stream = new MemoryStream(buffer)) { blob.UploadFromStream(stream, size, null, uploadOptions, null); // Ensure that the user stream is open. Assert.IsTrue(stream.CanSeek); } // Download the encrypted blob. // Create the decryption policy to be used for download. There is no need to specify the // key when the policy is only going to be used for downloads. Resolver is sufficient. BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver); // Set the decryption policy on the request options. BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy }; // Download and decrypt the encrypted contents from the blob. MemoryStream outputStream = new MemoryStream(); blob.DownloadToStream(outputStream, null, downloadOptions, null); // Ensure that the user stream is open. outputStream.Seek(0, SeekOrigin.Begin); // Compare that the decrypted contents match the input data. byte[] outputArray = outputStream.ToArray(); TestHelper.AssertBuffersAreEqualUptoIndex(outputArray, buffer, size - 1); } finally { container.DeleteIfExists(); } }
public void TableOperationEncryptionWithStrictMode() { // Insert Entity DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent.Properties.Add("foo2", new EntityProperty(string.Empty)); ent.Properties.Add("foo", new EntityProperty("bar")); ent.Properties.Add("fooint", new EntityProperty(1234)); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), EncryptionResolver = (pk, rk, propName) => { if (propName == "foo" || propName == "foo2") { return true; } return false; }, RequireEncryption = true }; currentTable.Execute(TableOperation.Insert(ent), options, null); // Insert an entity when RequireEncryption is set to true but no policy is specified. This should throw. options.EncryptionPolicy = null; TestHelper.ExpectedException<StorageException>( () => currentTable.Execute(TableOperation.Insert(ent), options, null), "Not specifying a policy when RequireEncryption is set to true should throw."); // Retrieve Entity TableRequestOptions retrieveOptions = new TableRequestOptions() { PropertyResolver = (pk, rk, propName, propValue) => { if (propName == "fooint") { return EdmType.Int32; } return (EdmType)0; }, EncryptionPolicy = new TableEncryptionPolicy(null, resolver), RequireEncryption = true }; TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey); Assert.IsFalse(operation.IsTableEntity); TableResult result = currentTable.Execute(operation, retrieveOptions, null); // Replace entity with plain text. ent.ETag = (result.Result as DynamicTableEntity).ETag; currentTable.Execute(TableOperation.Replace(ent)); // Retrieve with RequireEncryption flag but no metadata on the service. This should throw. TestHelper.ExpectedException<StorageException>( () => currentTable.Execute(operation, retrieveOptions, null), "Retrieving with RequireEncryption set to true and no metadata on the service should fail."); // Set RequireEncryption flag to true and retrieve. retrieveOptions.RequireEncryption = false; result = currentTable.Execute(operation, retrieveOptions, null); }
public void CloudQueueMessageEncryptionWithStrictMode() { // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the resolver to be used for unwrapping. DictionaryKeyResolver resolver = new DictionaryKeyResolver(); resolver.Add(aesKey); CloudQueueClient client = GenerateCloudQueueClient(); string name = GenerateNewQueueName(); CloudQueue queue = client.GetQueueReference(name); try { queue.CreateIfNotExists(); string messageStr = Guid.NewGuid().ToString(); CloudQueueMessage message = new CloudQueueMessage(messageStr); QueueEncryptionPolicy policy = new QueueEncryptionPolicy(aesKey, null); // Add message with policy. QueueRequestOptions createOptions = new QueueRequestOptions() { EncryptionPolicy = policy }; createOptions.RequireEncryption = true; queue.AddMessage(message, null, null, createOptions, null); // Set policy to null and add message while RequireEncryption flag is still set to true. This should throw. createOptions.EncryptionPolicy = null; TestHelper.ExpectedException<InvalidOperationException>( () => queue.AddMessage(message, null, null, createOptions, null), "Not specifying a policy when RequireEnryption is set to true should throw."); // Retrieve message QueueEncryptionPolicy retrPolicy = new QueueEncryptionPolicy(null, resolver); QueueRequestOptions retrieveOptions = new QueueRequestOptions() { EncryptionPolicy = retrPolicy }; retrieveOptions.RequireEncryption = true; CloudQueueMessage retrMessage = queue.GetMessage(null, retrieveOptions, null); // Update message with plain text. string updatedMessage = Guid.NewGuid().ToString("N"); retrMessage.SetMessageContent(updatedMessage); queue.UpdateMessage(retrMessage, TimeSpan.FromSeconds(0), MessageUpdateFields.Content | MessageUpdateFields.Visibility); // Retrieve updated message with RequireEncryption flag but no metadata on the service. This should throw. TestHelper.ExpectedException<StorageException>( () => queue.GetMessage(null, retrieveOptions, null), "Retrieving with RequireEncryption set to true and no metadata on the service should fail."); // Set RequireEncryption to false and retrieve. retrieveOptions.RequireEncryption = false; queue.GetMessage(null, retrieveOptions, null); } finally { queue.DeleteIfExists(); } }