/// <summary> /// Creates a secret in Azure Key Vault and returns its ID. /// </summary> /// <param name="secretName">The name of the secret to create.</param> /// <returns>The ID of the secret created.</returns> public static string SetUpKeyVaultSecret(string secretName) { KeyVaultClient cloudVault = new KeyVaultClient(GetAccessToken); string vaultUri = CloudConfigurationManager.GetSetting("VaultUri"); try { // Delete the secret if it exists. cloudVault.DeleteSecretAsync(vaultUri, secretName).GetAwaiter().GetResult(); } catch (KeyVaultClientException ex) { if (ex.Status != System.Net.HttpStatusCode.NotFound) { Console.WriteLine("Unable to access the specified vault. Please confirm the KVClientId, KVClientKey, and VaultUri are valid in the app.config file."); Console.WriteLine("Also ensure that the client ID has previously been granted full permissions for Key Vault secrets using the Set-AzureKeyVaultAccessPolicy command with the -PermissionsToSecrets parameter."); Console.WriteLine("Press any key to exit"); Console.ReadLine(); throw; } } // Create a 256bit symmetric key and convert it to Base64. SymmetricKey symmetricKey = new SymmetricKey(secretName, SymmetricKey.KeySize256); string symmetricBytes = Convert.ToBase64String(symmetricKey.Key); // Store the Base64 of the key in the key vault. Note that the content-type of the secret must // be application/octet-stream or the KeyVaultKeyResolver will not load it as a key. Secret cloudSecret = cloudVault.SetSecretAsync(vaultUri, secretName, symmetricBytes, null, "application/octet-stream").GetAwaiter().GetResult(); // Return the base identifier of the secret. This will be resolved to the current version of the secret. return cloudSecret.SecretIdentifier.BaseIdentifier; }
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 TableEncryptingUnsupportedPropertiesShouldThrow() { // 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("fooint", new EntityProperty(1234)); // 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.StartsWith("foo")) { return true; } return false; } }; StorageException e = TestHelper.ExpectedException<StorageException>( () => currentTable.Execute(TableOperation.Insert(ent), options, null), "Encrypting non-string properties should fail"); Assert.IsInstanceOfType(e.InnerException, typeof(InvalidOperationException)); ent.Properties.Remove("fooint"); ent.Properties.Add("foo", null); e = TestHelper.ExpectedException<StorageException>( () => currentTable.Execute(TableOperation.Insert(ent), options, null), "Encrypting null properties should fail"); Assert.IsInstanceOfType(e.InnerException, typeof(InvalidOperationException)); }
private void DoTableOperationValidateEncryption(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // Insert Entity DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent.Properties.Add("encprop", new EntityProperty(String.Empty)); ent.Properties.Add("encprop2", new EntityProperty(String.Empty)); ent.Properties.Add("encprop3", new EntityProperty("bar")); ent.Properties.Add("notencprop", new EntityProperty(1234)); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); TableRequestOptions uploadOptions = new TableRequestOptions() { PropertyResolver = (pk, rk, propName, propValue) => { if (propName == "notencprop") { return EdmType.Int32; } return (EdmType)0; }, EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), EncryptionResolver = (pk, rk, propName) => { if (propName.StartsWith("encprop")) { return true; } return false; } }; currentTable.Execute(TableOperation.Insert(ent), uploadOptions, null); TableRequestOptions downloadOptions = new TableRequestOptions() { PropertyResolver = (pk, rk, propName, propValue) => { if (propName == "notencprop") { return EdmType.Int32; } return (EdmType)0; } }; // Retrieve Entity without decrypting TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey); Assert.IsFalse(operation.IsTableEntity); TableResult result = currentTable.Execute(operation, downloadOptions, null); DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; Assert.IsNotNull(retrievedEntity); Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); // Properties having the same value should be encrypted to different values. if (format == TablePayloadFormat.JsonNoMetadata) { // With DTE and Json no metadata, if an encryption policy is not set, the client lib just reads the byte arrays as strings. Assert.AreNotEqual(retrievedEntity.Properties["encprop"].StringValue, retrievedEntity.Properties["encprop2"].StringValue); } else { CollectionAssert.AreNotEqual(retrievedEntity.Properties["encprop"].BinaryValue, retrievedEntity.Properties["encprop2"].BinaryValue); Assert.AreNotEqual(ent.Properties["encprop"].PropertyType, retrievedEntity.Properties["encprop"].PropertyType); Assert.AreNotEqual(ent.Properties["encprop2"].PropertyType, retrievedEntity.Properties["encprop2"].PropertyType); Assert.AreNotEqual(ent.Properties["encprop3"].PropertyType, retrievedEntity.Properties["encprop3"].PropertyType); } Assert.AreEqual(ent.Properties["notencprop"].Int32Value, retrievedEntity.Properties["notencprop"].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 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 TableQueryPOCOProjectionEncryption() { // 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); // Query with different payload formats. DoTableQueryPOCOProjectionEncryption(TablePayloadFormat.Json, aesKey); DoTableQueryPOCOProjectionEncryption(TablePayloadFormat.JsonNoMetadata, aesKey); DoTableQueryPOCOProjectionEncryption(TablePayloadFormat.JsonFullMetadata, aesKey); DoTableQueryPOCOProjectionEncryption(TablePayloadFormat.AtomPub, aesKey); }
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); }
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 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 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(); } }
public void CloudBlobEncryptionWithStrictModeOnPartialBlob() { CloudBlobContainer container = GetRandomContainerReference(); int size = 5 * 1024 * 1024; byte[] buffer = GetRandomBuffer(size); ICloudBlob blob; MemoryStream stream = new MemoryStream(buffer); String blockId = Convert.ToBase64String(Guid.NewGuid().ToByteArray()); BlobRequestOptions options = new BlobRequestOptions() { RequireEncryption = true }; blob = container.GetBlockBlobReference("blob1"); try { ((CloudBlockBlob)blob).PutBlock(blockId, stream, null, null, options, null); Assert.Fail("PutBlock with RequireEncryption on should fail."); } catch (InvalidOperationException ex) { Assert.AreEqual(ex.Message, SR.EncryptionPolicyMissingInStrictMode); } blob = container.GetPageBlobReference("blob1"); try { ((CloudPageBlob)blob).WritePages(stream, 0, null, null, options, null); Assert.Fail("WritePages with RequireEncryption on should fail."); } catch (InvalidOperationException ex) { Assert.AreEqual(ex.Message, SR.EncryptionPolicyMissingInStrictMode); } blob = container.GetAppendBlobReference("blob1"); try { ((CloudAppendBlob)blob).AppendBlock(stream, null, null, options, null); Assert.Fail("AppendBlock with RequireEncryption on should fail."); } catch (InvalidOperationException ex) { Assert.AreEqual(ex.Message, SR.EncryptionPolicyMissingInStrictMode); } // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); options.EncryptionPolicy = new BlobEncryptionPolicy(aesKey, null); blob = container.GetBlockBlobReference("blob1"); try { ((CloudBlockBlob)blob).PutBlock(blockId, stream, null, null, options, null); Assert.Fail("PutBlock with an EncryptionPolicy should fail."); } catch (InvalidOperationException ex) { Assert.AreEqual(ex.Message, SR.EncryptionNotSupportedForOperation); } blob = container.GetPageBlobReference("blob1"); try { ((CloudPageBlob)blob).WritePages(stream, 0, null, null, options, null); Assert.Fail("WritePages with an EncryptionPolicy should fail."); } catch (InvalidOperationException ex) { Assert.AreEqual(ex.Message, SR.EncryptionNotSupportedForOperation); } blob = container.GetAppendBlobReference("blob1"); try { ((CloudAppendBlob)blob).AppendBlock(stream, null, null, options, null); Assert.Fail("AppendBlock with an EncryptionPolicy should fail."); } catch (InvalidOperationException ex) { Assert.AreEqual(ex.Message, SR.EncryptionNotSupportedForOperation); } }
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 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(); }
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(); }
public void CloudBlockBlobValidateEncryptionAPM() { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); int size = 5 * 1024 * 1024; byte[] buffer = GetRandomBuffer(size); CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // 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. MemoryStream 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); } // Encrypt locally. CryptoStream encryptedStream; using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider()) { string metadata = blob.Metadata[Constants.EncryptionConstants.BlobEncryptionData]; BlobEncryptionData encryptionData = JsonConvert.DeserializeObject<BlobEncryptionData>(metadata); myAes.IV = encryptionData.ContentEncryptionIV; myAes.Key = aesKey.UnwrapKeyAsync(encryptionData.WrappedContentKey.EncryptedKey, encryptionData.WrappedContentKey.Algorithm, CancellationToken.None).Result; stream.Seek(0, SeekOrigin.Begin); encryptedStream = new CryptoStream(stream, myAes.CreateEncryptor(), CryptoStreamMode.Read); } // Download the encrypted blob. MemoryStream outputStream = new MemoryStream(); using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { ICancellableAsyncResult result = blob.BeginDownloadToStream(outputStream, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blob.EndDownloadToStream(result); } outputStream.Seek(0, SeekOrigin.Begin); for (int i = 0; i < outputStream.Length; i++) { Assert.AreEqual(encryptedStream.ReadByte(), outputStream.ReadByte()); } } finally { container.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); } }
private void ValidateRangeDecryption(BlobType type, int blobSize, int? blobOffset, int? length, int? verifyLength = null) { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); byte[] buffer = GetRandomBuffer(blobSize); ICloudBlob blob = GetCloudBlobReference(type, container); // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // Create the encryption policy to be used for upload. BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(aesKey, null); // Set the encryption policy on the request options. BlobRequestOptions options = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; // Upload the encrypted contents to the blob. MemoryStream stream = new MemoryStream(buffer); blob.UploadFromStream(stream, blobSize, null, options, null); // Download a range in the encrypted blob. MemoryStream outputStream = new MemoryStream(); blob.DownloadRangeToStream(outputStream, blobOffset, length, null, options, null); outputStream.Seek(0, SeekOrigin.Begin); if (length.HasValue) { if (verifyLength.HasValue) { Assert.AreEqual(verifyLength.Value, outputStream.Length); } else { Assert.AreEqual(length.Value, outputStream.Length); } } // Compare that the decrypted contents match the input data. byte[] outputArray = outputStream.ToArray(); for (int i = 0; i < outputArray.Length; i++) { int bufferOffset = (int) (blobOffset.HasValue ? blobOffset : 0); Assert.AreEqual(buffer[bufferOffset + i], outputArray[i]); } } finally { container.DeleteIfExists(); } }
public void TableQueryDTEProjectionEncryption() { // Insert Entity DynamicTableEntity ent1 = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent1.Properties.Add("A", new EntityProperty(String.Empty)); ent1.Properties.Add("B", new EntityProperty("b")); DynamicTableEntity ent2 = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; ent2.Properties.Add("A", new EntityProperty("a")); ent2.Properties.Add("B", new EntityProperty("b")); // 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") { return true; } return false; } }; currentTable.Execute(TableOperation.Insert(ent1), options, null); currentTable.Execute(TableOperation.Insert(ent2), options, null); // Query with different payload formats. DoTableQueryDTEProjectionEncryption(TablePayloadFormat.Json, aesKey); DoTableQueryDTEProjectionEncryption(TablePayloadFormat.JsonNoMetadata, aesKey); DoTableQueryDTEProjectionEncryption(TablePayloadFormat.JsonFullMetadata, aesKey); DoTableQueryDTEProjectionEncryption(TablePayloadFormat.AtomPub, aesKey); }
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 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)); } }
private void DoBlobEncryptedWriteStreamTestAPM(BlobType type) { byte[] buffer = GetRandomBuffer(8 * 1024); CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); ICloudBlob blob = null; // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); // 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 }; OperationContext opContext = new OperationContext(); CloudBlobStream blobStream = null; using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { IAsyncResult result; if (type == BlobType.BlockBlob) { blob = container.GetBlockBlobReference("blob1"); blob.StreamWriteSizeInBytes = 16 * 1024; result = ((CloudBlockBlob)blob).BeginOpenWrite(null, uploadOptions, opContext, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blobStream = ((CloudBlockBlob)blob).EndOpenWrite(result); } else if (type == BlobType.PageBlob) { blob = container.GetPageBlobReference("blob1"); blob.StreamWriteSizeInBytes = 16 * 1024; result = ((CloudPageBlob)blob).BeginOpenWrite(40 * 1024, null, uploadOptions, opContext, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blobStream = ((CloudPageBlob)blob).EndOpenWrite(result); } else { blob = container.GetAppendBlobReference("blob1"); blob.StreamWriteSizeInBytes = 16 * 1024; result = ((CloudAppendBlob)blob).BeginOpenWrite(true, null, uploadOptions, opContext, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blobStream = ((CloudAppendBlob)blob).EndOpenWrite(result); } } using (MemoryStream wholeBlob = new MemoryStream()) { using (blobStream) { using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { IAsyncResult result; for (int i = 0; i < 3; i++) { result = blobStream.BeginWrite( buffer, 0, buffer.Length, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blobStream.EndWrite(result); wholeBlob.Write(buffer, 0, buffer.Length); } // Append and Page blobs have one extra call due to create. if (type == BlobType.BlockBlob) { Assert.AreEqual(1, opContext.RequestResults.Count); } else { Assert.AreEqual(2, opContext.RequestResults.Count); } result = blobStream.BeginWrite( buffer, 0, buffer.Length, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blobStream.EndWrite(result); wholeBlob.Write(buffer, 0, buffer.Length); result = blobStream.BeginWrite( buffer, 0, buffer.Length, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blobStream.EndWrite(result); wholeBlob.Write(buffer, 0, buffer.Length); // Append and Page blobs have one extra call due to create. if (type == BlobType.BlockBlob) { Assert.AreEqual(2, opContext.RequestResults.Count); } else { Assert.AreEqual(3, opContext.RequestResults.Count); } result = blobStream.BeginCommit( ar => waitHandle.Set(), null); waitHandle.WaitOne(); blobStream.EndCommit(result); Assert.AreEqual(4, opContext.RequestResults.Count); } } Assert.AreEqual(4, opContext.RequestResults.Count); using (MemoryStream downloadedBlob = new MemoryStream()) { blob.DownloadToStream(downloadedBlob, null, uploadOptions); TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); } } } finally { container.DeleteIfExists(); } }
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"]); }
public void TableOperationEncryptionWithStrictModeOnMerge() { // 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)); ent.ETag = "*"; TableRequestOptions options = new TableRequestOptions() { RequireEncryption = true }; try { currentTable.Execute(TableOperation.Merge(ent), options, null); Assert.Fail("Merge with RequireEncryption on should fail."); } catch (StorageException ex) { Assert.AreEqual(ex.Message, SR.EncryptionPolicyMissingInStrictMode); } try { currentTable.Execute(TableOperation.InsertOrMerge(ent), options, null); Assert.Fail("InsertOrMerge with RequireEncryption on should fail."); } catch (StorageException ex) { Assert.AreEqual(ex.Message, SR.EncryptionPolicyMissingInStrictMode); } // Create the Key to be used for wrapping. SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); options.EncryptionPolicy = new TableEncryptionPolicy(aesKey, null); try { currentTable.Execute(TableOperation.Merge(ent), options, null); Assert.Fail("Merge with an EncryptionPolicy should fail."); } catch (StorageException ex) { Assert.AreEqual(ex.Message, SR.EncryptionNotSupportedForOperation); } try { currentTable.Execute(TableOperation.InsertOrMerge(ent), options, null); Assert.Fail("InsertOrMerge with an EncryptionPolicy should fail."); } catch (StorageException ex) { Assert.AreEqual(ex.Message, SR.EncryptionNotSupportedForOperation); } }
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); }
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."); }
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 TableOperationsIgnoreEncryptionAsync() { SymmetricKey aesKey = new SymmetricKey("symencryptionkey"); TableRequestOptions options = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(aesKey, null), RequireEncryption = true }; CloudTable testTable = this.tableClient.GetTableReference(GenerateRandomTableName()); try { // Check Create() testTable.CreateAsync(options, null).Wait(); Assert.IsTrue(testTable.Exists(), "Table failed to be created when encryption policy was supplied."); // Check Exists() Assert.IsTrue(testTable.ExistsAsync(options, null).Result, "Table.Exists() failed when encryption policy was supplied."); // Check ListTables(). Assert.AreEqual(testTable.Name, this.ListAllTablesAsync(this.tableClient, testTable.Name, options).Result.First().Name, "ListTables failed when an encryption policy was specified."); // Check Get and Set Permissions TablePermissions permissions = testTable.GetPermissions(); string policyName = "samplePolicy"; permissions.SharedAccessPolicies.Add(policyName, new SharedAccessTablePolicy() { Permissions = SharedAccessTablePermissions.Query, SharedAccessExpiryTime = DateTime.Now + TimeSpan.FromDays(1) }); testTable.SetPermissionsAsync(permissions, options, null).Wait(); Assert.AreEqual(policyName, testTable.GetPermissions().SharedAccessPolicies.First().Key); Assert.AreEqual(policyName, testTable.GetPermissionsAsync(options, null).Result.SharedAccessPolicies.First().Key); // Check Delete testTable.DeleteAsync(options, null).Wait(); Assert.IsFalse(testTable.Exists()); } finally { testTable.DeleteIfExists(); } }