Azure Key Vault - Download original PFX from Ket Vault - azure

I dont have a great understanding of Key Vault & certificates and struggling with an issue. I am making use of a PFX file to generate a JWT token to call an external webservice. Its working all right. Now I need to store the PFX in Key Vault and do the same.
I am uploading the cert using Az DevOps & Az Cli command
az keyvault certificate import --file $(filename.secureFilePath) --name pfx-cert-name --vault-name "keyvault-name" --password "password"
Now when I try to use the PFX in my .net core. I am using CertificateClient class & GetCertificateAsync methods to fetch the byte array of a PFX file.
var client = new CertificateClient(new Uri(kvUri), new DefaultAzureCredential()); var cert = await client.GetCertificateAsync(certName);
certInBytes = cert.Value.Cer;
The code fails. After doing online reading, I understand its because Get Certificate fetches the public details of the PFX file. Hence I started doing some reading online and doing import and download using Az Cli command on powershell.
I tried another technique to download original form of PFX using the below command:
az keyvault secret download --file inputCert.pfx --vault-name keyvault-name --encoding base64 --name pfx-cert-name
The command gives me another pfx but its still not the original form of PFX. When I try to use this cert to get JWT token, I get an error for invalid password.
I have two alternates, but I don't want to use either as they are not clean solutions:
Either store a byte array of PFX as a secret in key vault
Store base 64 encoded version of byte array of pfx for extra security.

To get the certificate with its private key, then you need to download it as a secret, not as a certificate. Yes, it does sounds weird, by that is how you do it.
This is the code I use to download a certificate with private key from AKV:
/// <summary>
/// Load a certificate (with private key) from Azure Key Vault
///
/// Getting a certificate with private key is a bit of a pain, but the code below solves it.
///
/// Get the private key for Key Vault certificate
/// https://github.com/heaths/azsdk-sample-getcert
///
/// See also these GitHub issues:
/// https://github.com/Azure/azure-sdk-for-net/issues/12742
/// https://github.com/Azure/azure-sdk-for-net/issues/12083
/// </summary>
/// <param name="config"></param>
/// <param name="certificateName"></param>
/// <returns></returns>
public static X509Certificate2 LoadCertificate(IConfiguration config, string certificateName)
{
string vaultUrl = config["Vault:Url"] ?? "";
string clientId = config["Vault:ClientId"] ?? "";
string tenantId = config["Vault:TenantId"] ?? "";
string secret = config["Vault:ClientSecret"] ?? "";
Console.WriteLine($"Loading certificate '{certificateName}' from Azure Key Vault");
var credentials = new ClientSecretCredential(tenantId: tenantId, clientId: clientId, clientSecret: secret);
var certClient = new CertificateClient(new Uri(vaultUrl), credentials);
var secretClient = new SecretClient(new Uri(vaultUrl), credentials);
var cert = GetCertificateAsync(certClient, secretClient, certificateName);
Console.WriteLine("Certificate loaded");
return cert;
}
/// <summary>
/// Helper method to get a certificate
///
/// Source https://github.com/heaths/azsdk-sample-getcert/blob/master/Program.cs
/// </summary>
/// <param name="certificateClient"></param>
/// <param name="secretClient"></param>
/// <param name="certificateName"></param>
/// <returns></returns>
private static X509Certificate2 GetCertificateAsync(CertificateClient certificateClient,
SecretClient secretClient,
string certificateName)
{
KeyVaultCertificateWithPolicy certificate = certificateClient.GetCertificate(certificateName);
// Return a certificate with only the public key if the private key is not exportable.
if (certificate.Policy?.Exportable != true)
{
return new X509Certificate2(certificate.Cer);
}
// Parse the secret ID and version to retrieve the private key.
string[] segments = certificate.SecretId.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (segments.Length != 3)
{
throw new InvalidOperationException($"Number of segments is incorrect: {segments.Length}, URI: {certificate.SecretId}");
}
string secretName = segments[1];
string secretVersion = segments[2];
KeyVaultSecret secret = secretClient.GetSecret(secretName, secretVersion);
// For PEM, you'll need to extract the base64-encoded message body.
// .NET 5.0 preview introduces the System.Security.Cryptography.PemEncoding class to make this easier.
if ("application/x-pkcs12".Equals(secret.Properties.ContentType, StringComparison.InvariantCultureIgnoreCase))
{
byte[] pfx = Convert.FromBase64String(secret.Value);
return new X509Certificate2(pfx);
}
throw new NotSupportedException($"Only PKCS#12 is supported. Found Content-Type: {secret.Properties.ContentType}");
}
}
The code above depends on these NuGet packages:
Azure.Security.KeyVault.Certificates
Azure.Security.KeyVault.Keys
Azure.Security.KeyVault.Secrets

There are 2 ways to solve this problem. One with the help of DefaultCredentials class while the other solution being with the help of a SPN using class ClientSecretCredentials.
I have written a detailed article on both the solution. Since the original problem was in regards to DefaultCredentials, I wrote about it first
https://blog.devgenius.io/fetch-pfx-cert-from-key-vault-using-defaultcredentials-3795bd23d294?sk=be8a6fea080ff19056a0b90fc9532cd7
https://blog.devgenius.io/fetch-pfx-cert-from-key-vault-using-clientsecretcredentials-c0e80b129b37?sk=63c93f776bde72f49ef12263838e8d82

Related

Azure - Create Database via HTTP API (using Secret) - 403 Error

I am trying to create an Azure Database programmatically using C# via the HTTP API.
I found this resource (in which he uses App Secret, rather than certificate), but can't get it to work due to a 403: Forbidden error.
If I use the token created in the 'try it' section of the azure docs, the code works fine, so it must be that the token generated doesn't have the permissions I need.
The secret I am trying to use was generated in Portal > Active Directory > App Registrations > {myapp} > Certificates and Secrets.
In API permissions I've added just about everything - though please suggest any I might have missed!
I opened the firewall to my IP and have spent hours looking for the answer, but can't seem to figure it out.
What am I missing please?
Although I believe it's permissions somewhere in Azure, here's my code:
/// <summary>
/// Create a new database
/// </summary>
/// <param name="subscriptionId">See Portal > Subscriptions (pick the right subscription!)</param>
/// <param name="resourceGroupName">The resource group the server was created in</param>
/// <param name="locationName">e.g. UK (South)</param>
/// <param name="sqlServeName">The name of the SQL Server VM created when the first database was created</param>
/// <param name="tenantId">See GetAccessToken</param>
/// <param name="clientId">See GetAccessToken</param>
/// <param name="clientSecret">See GetAccessToken</param>
/// <param name="databaseName">The name of the database to be created</param>
/// <returns></returns>
private async Task CreateDatabaseAsync(string subscriptionId, string resourceGroupName, string locationName, string sqlServeName, string tenantId, string clientId, string clientSecret, string databaseName)
{
var token = await GetAccessTokenAsync(tenantId, clientId, clientSecret);
var url = "https://management.azure.com/subscriptions/" + subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Sql/servers/" + sqlServeName + "/databases/" + databaseName + "?api-version=2017-10-01-preview";
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Remove("Authorization");
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
string requestBody = "{location: \"" + locationName + "\"}";
HttpResponseMessage response = await httpClient.PutAsync(url, new StringContent(requestBody, Encoding.UTF8, "application/json"));
var statusCode = response.StatusCode.ToString();
}
/// <summary>
/// Gets and access token with which to call the Azure API
/// </summary>
/// <param name="tenantId">See Portal > Active Directory > Properties > Overview for this value</param>
/// <param name="clientId">See Portal > Active Directory > App Registrations > This App > Overview for this value</param>
/// <param name="clientSecret">See Portal > Active Directory > App Registrations > This App > Certificates & Secrets > Generate Secret </param>
/// <returns></returns>
private async Task<string> GetAccessTokenAsync(string tenantId, string clientId, string clientSecret)
{
Console.WriteLine("Begin GetAccessToken");
string authContextURL = "https://login.windows.net/" + tenantId;
var authenticationContext = new AuthenticationContext(authContextURL);
var credential = new ClientCredential(clientId, clientSecret);
var result = await authenticationContext
.AcquireTokenAsync("https://management.azure.com/", credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
}
Managed to find the answer in this post/ this Microsoft Article.
What I needed to do was:
Go to Portal > Subscriptions > {my subscription}
Click on Access control (IAM)
Add > Add Role Assignment as shown below (note: 'SqlTest' is the Application I created in Portal > Azure Active Directory > App Registrations)
Then the code works nicely.

Azure Ad authentication by passing username and password to get the jwt token

Currently i am trying to implement the azure active directory authentication by passing user name and password. So for this i have trying to get the access toke but facing issue to get the same. If i use the client id and client secret then i am able to get the token but when i try to by passing username and password then its not giving the result and throwing the exception :
"error":"invalid_client","error_description":"AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'
Below the code which i am using for this:
/// <summary>
/// Working with client id and client secret
/// </summary>
/// <returns></returns>
public async Task<string> GetTokenUsingClientSecret()
{
//authentication parameters
string clientID = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
string clientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXX";
string directoryName = "xxx.onmicrosoft.com";
var credential = new ClientCredential(clientID, clientSecret);
var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/" + directoryName, false);
var result = await authenticationContext.AcquireTokenAsync("https://management.core.windows.net/", clientCredential: credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
}
/// <summary>
/// Not Working with username and password.
/// </summary>
public async Task<string> GetTokenUsingUserNamePassword()
{
try
{
string user = "username.onmicrosoft.com";
string pass = "yourpassword";
string directoryName = "XXXX.onmicrosoft.com";
string authority = "https://login.microsoftonline.com";
string resource = "https://management.core.windows.net/";
string clientId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var credentials = new UserPasswordCredential(user, pass);
var authenticationContext = new AuthenticationContext($"{authority}/{directoryName}");
var result = authenticationContext.AcquireTokenAsync(resource: resource, clientId: clientId, userCredential: credentials);
return result.Result.AccessToken;
}
catch (Exception ex)
{
throw ex;
}
}
AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.
According to your mentioned exception, I assume that you registry an Azure AD Web app/API application. Please have a try to use an Azure AD native appilcation then it should work. More details you could refer to this document -Constraints & Limitations section.
No web sites/confidential clients
This is not an ADAL limitation, but an AAD setting. You can only use those flows from a native client. A confidential client, such as a web site, cannot use direct user credentials.
How to reigstry Azure AD native Application.

"Error occurred while decoding OAEP padding" while decrypting data from table storage

Reaching out to for your help / support.
We have a requirement to Encrypt the data in table storage and Decrypt the data while pulling it from table storage. Tried with the sample application found in https://github.com/Azure/azure-storage-net.
In the sample application Encryption and Decyption is happening in same method. In my case it rasing error in "Decrypt" function and the error is - "Error occurred while decoding OAEP padding" But we need to two separate functions. Even we need to pull the data through Table Query.
Please find below is my code -
const string DemoTable = "demotable";
static void Main(string[] args)
{
RsaKey key = new RsaKey("mydemokey");
string partitionid = "mydemoid123456";
EncryptData(partitionid, key);
DecryptData(partitionid, key);
}
public static void EncryptData(string partitionid, RsaKey rsakey)
{
CloudStorageAccount storageAccount = EncryptionShared.Utility.CreateStorageAccountFromConnectionString();
CloudTableClient client = storageAccount.CreateCloudTableClient();
CloudTable table = client.GetTableReference(DemoTable);
try
{
table.Create();
EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" };
ent.Populate();
TableRequestOptions insertOptions = new TableRequestOptions()
{
EncryptionPolicy = new TableEncryptionPolicy(rsakey, null)
};
table.Execute(TableOperation.Insert(ent), insertOptions, null);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
}
public static void DecryptData(string partitionid, RsaKey rsakey)
{
CloudStorageAccount storageAccount = EncryptionShared.Utility.CreateStorageAccountFromConnectionString();
CloudTableClient client = storageAccount.CreateCloudTableClient();
CloudTable table = client.GetTableReference(DemoTable);
try
{
EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" };
ent.Populate();
LocalResolver resolver = new LocalResolver();
resolver.Add(rsakey);
TableRequestOptions retrieveOptions = new TableRequestOptions()
{
EncryptionPolicy = new TableEncryptionPolicy(null, resolver)
};
TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey);
TableResult result = table.Execute(operation, retrieveOptions, null);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
}
}
Am I doing any mistake or any other option available to Encypt and Decrypt the data in Table Storage (including partitionkey).
Decrypt Error
Thanks in advance for your help.
Best Regards,
Debasis
According to your codes, I found you add the rsakey to the LocalResolver object in the DecryptData method.
As far as I know, the raskey is a one-time-use symmetric key and its value is not same after generated.
If you don’t use the right raskey(generated when you update the table entity), you couldn’t get the right result from the table storage.
More details about how the client-side encryption worked you could refer to follow step and link:
Encryption via the envelope technique works in the following way:
The Azure storage client library generates a content encryption key (CEK), which is a one-time-use symmetric key.
User data is encrypted using this CEK.
The CEK is then wrapped (encrypted) using the key encryption key (KEK). The KEK is identified by a key identifier and can be an asymmetric key pair or a symmetric key and can be managed locally or stored in Azure Key Vaults.
The storage client library itself never has access to KEK. The library invokes the key wrapping algorithm that is provided by Key Vault. Users can choose to use custom providers for key wrapping/unwrapping if desired.
The encrypted data is then uploaded to the Azure Storage service. The wrapped key along with some additional encryption metadata is either stored as metadata (on a blob) or interpolated with the encrypted data (queue messages and table entities).
Decryption via the envelope technique works in the following way:
The client library assumes that the user is managing the key encryption key (KEK) either locally or in Azure Key Vaults. The user does not need to know the specific key that was used for encryption. Instead, a key resolver which resolves different key identifiers to keys can be set up and used.
The client library downloads the encrypted data along with any encryption material that is stored on the service.
The wrapped content encryption key (CEK) is then unwrapped (decrypted) using the key encryption key (KEK). Here again, the client library does not have access to KEK. It simply invokes the custom or Key Vault provider’s unwrapping algorithm.
The content encryption key (CEK) is then used to decrypt the encrypted user data.
Link:https://learn.microsoft.com/en-us/azure/storage/storage-client-side-encryption
I suggest you could use below codes to get the right result.
class Program
{
const string DemoTable = "demotable";
const string ConnectionString = "yourconnectionstring";
// For retrieves, a resolver can be set up that will help pick the key based on the key id.
static LocalResolver resolver = new LocalResolver();
static void Main(string[] args)
{
RsaKey key = new RsaKey("mydemokey");
string partitionid = "mydemoid123456";
EncryptData(partitionid, key);
DecryptData(partitionid, key);
}
public static void EncryptData(string partitionid, RsaKey rsakey)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
CloudTableClient client = storageAccount.CreateCloudTableClient();
CloudTable table = client.GetTableReference(DemoTable);
try
{
table.CreateIfNotExists();
EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" ,Test = "aaaa" };
//ent.Populate();
TableRequestOptions insertOptions = new TableRequestOptions()
{
EncryptionPolicy = new TableEncryptionPolicy(rsakey, null)
};
resolver.Add(rsakey);
table.Execute(TableOperation.Insert(ent), insertOptions, null);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
}
public static void DecryptData(string partitionid, RsaKey rsakey)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
CloudTableClient client = storageAccount.CreateCloudTableClient();
CloudTable table = client.GetTableReference(DemoTable);
try
{
EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" };
//ent.Populate();
TableRequestOptions retrieveOptions = new TableRequestOptions()
{
EncryptionPolicy = new TableEncryptionPolicy(null, resolver)
};
TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey);
TableResult result = table.Execute(operation, retrieveOptions, null);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
}
}
Result:
Besides, the example above stored the key value in the local, normally we will use the Azure Key Vault service to store key.
More details, you could refer to follow link:
What is Azure Key Vault?
Encrypt and decrypt in Microsoft Azure Storage using Azure Key Vault

any sample for creating an instance of SamlSecurityToken?

I'm not sure if its a good question or not but:
I'm trying to find any sample for creating an instance of System.IdentityModel.Tokens.SamlSecurityToken and System.IdentityModel.Tokens.SamlAssertion on the internet but I couln't find...any help?
Got it!
Source (server was not responding in the time I wrote the question):
http://developers.de/blogs/damir_dobric/archive/2007/02/22/Creating-of-SAML-token.aspx
private static void Main(string[] args)
{
SamlAssertion assertion = createSamlAssertion();
SamlSecurityToken samlToken = new SamlSecurityToken(assertion);
}
/// <summary>
/// Creates some Test SAML assertion
/// </summary>
/// <returns></returns>
private static SamlAssertion createSamlAssertion()
{
// Here we create some SAML assertion with ID and Issuer name.
SamlAssertion assertion = new SamlAssertion();
assertion.AssertionId = "DaenetSamlTest";
assertion.Issuer = "damir";
//
// Create some SAML subject.
SamlSubject samlSubject = new SamlSubject();
samlSubject.Name = "My Subject";
//
// Create one SAML attribute with few values.
SamlAttribute attr = new SamlAttribute();
attr.Namespace = http://daenet.eu/saml;
attr.AttributeValues.Add("Some Value 1");
attr.AttributeValues.Add("Some Value 2");
attr.Name = "My ATTR Value";
//
// Now create the SAML statement containing one attribute and one subject.
SamlAttributeStatement samlAttributeStatement = new SamlAttributeStatement();
samlAttributeStatement.Attributes.Add(attr);
samlAttributeStatement.SamlSubject = samlSubject;
// Append the statement to the SAML assertion.
assertion.Statements.Add(samlAttributeStatement);
return assertion;
}
And this is for signing the assertion
/// <summary>
/// Creates some signed Test SAML assertion.
/// </summary>
/// <returns></returns>
private static SamlAssertion createSamlAssertion()
{
//
// Create certificate from file. It must contain private key!
X509Certificate2 cert = new X509Certificate2("filename.cert");
// The private key contained in the certificate will be used to sign the
token.
X509AsymmetricSecurityKey signingKey = new X509AsymmetricSecurityKey(cert);
SamlAssertion assertion = createSamlAssertion();
//
// Signing credentials are consisted
// of private key in the certificate (see above),
// the signature algorithm, security algortihm and key identifier.
assertion.SigningCredentials =
new SigningCredentials(signingKey, SecurityAlgorithms.RsaSha1Signature,
SecurityAlgorithms.Sha1Digest,
new SecurityKeyIdentifier(new X509ThumbprintKeyIdentifierClause(cert)));
// Finally create the SamlSecurityToken from the assertion
SamlSecurityToken samlToken = new SamlSecurityToken(assertion);
// Create a SecurityTokenSerializer that
// will be used to serialize the SamlSecurityToken
WSSecurityTokenSerializer ser = new WSSecurityTokenSerializer();
using (XmlWriter xWriter = XmlWriter.Create("saml.xml"))
{
ser.WriteToken(xWriter, samlToken);
}
}

Which thumb print should be used to list the hosted services using windows azure management api

I want to list all the hosted services using Azure service Management REST Api. And the msdn hlep explains a way to list hosted services. I have attached the example code given in msdn.
In the code they have used Version, Thumbprint and SubscriptionId.
In windows azure portal we can see a subcription has a subcription Id. And a certificate has a Thumbprint. There may be many hosted services in one subcription so many certificates as well. So what is the thumbprint the following code has mentioned..?
Should it checked with all the thumbprints of a subcription , to list all the hosted services in a subcription.
Why can't we get all the hosted services just using the subcriptionId (is it not secured?) Or is there a common certificate(so there is a thumbprint) for a subcription?
Please guide me,
Thanks.
namespace Microsoft.WindowsAzure.ServiceManagementRESTAPI.Samples
{
using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using System.Xml.Linq;
public class Program
{
// Set these constants with your values to run the sample.
private const string Version = "2011-10-01";
private const string Thumbprint = "management-certificate-thumbprint";
private const string SubscriptionId = "subscription-id";
static void Main(string[] args)
{
try
{
// Obtain the certificate with the specified thumbprint
X509Certificate2 certificate = GetStoreCertificate(Thumbprint);
ListHostedServicesExample(SubscriptionId, certificate, Version);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in Main:");
Console.WriteLine(ex.Message);
}
Console.Write("Press any key to continue:");
Console.ReadKey();
}
public static void ListHostedServicesExample(
string subscriptionId,
X509Certificate2 certificate,
string version)
{
string uriFormat = "https://management.core.windows.net/{0}/" +
"services/hostedservices";
Uri uri = new Uri(String.Format(uriFormat, subscriptionId));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "GET";
request.Headers.Add("x-ms-version", version);
request.ClientCertificates.Add(certificate);
request.ContentType = "application/xml";
XDocument responseBody = null;
HttpStatusCode statusCode;
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
// GetResponse throws a WebException for 400 and 500 status codes
response = (HttpWebResponse)ex.Response;
}
statusCode = response.StatusCode;
if (response.ContentLength > 0)
{
using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
{
responseBody = XDocument.Load(reader);
}
}
response.Close();
if (statusCode.Equals(HttpStatusCode.OK))
{
XNamespace wa = "http://schemas.microsoft.com/windowsazure";
XElement hostedServices = responseBody.Element(wa + "HostedServices");
Console.WriteLine(
"Hosted Services for Subscription ID {0}:{1}{2}",
subscriptionId,
Environment.NewLine,
hostedServices.ToString(SaveOptions.OmitDuplicateNamespaces));
}
else
{
Console.WriteLine("Call to List Hosted Services returned an error:");
Console.WriteLine("Status Code: {0} ({1}):{2}{3}",
(int)statusCode, statusCode, Environment.NewLine,
responseBody.ToString(SaveOptions.OmitDuplicateNamespaces));
}
return;
}
/// <summary>
/// Gets the certificate matching the thumbprint from the local store.
/// Throws an ArgumentException if a matching certificate is not found.
/// </summary>
/// <param name="thumbprint">The thumbprint of the certificate to find.</param>
/// <returns>The certificate with the specified thumbprint.</returns>
private static X509Certificate2 GetStoreCertificate(string thumbprint)
{
List<StoreLocation> locations = new List<StoreLocation>
{
StoreLocation.CurrentUser,
StoreLocation.LocalMachine
};
foreach (var location in locations)
{
X509Store store = new X509Store("My", location);
try
{
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection certificates = store.Certificates.Find(
X509FindType.FindByThumbprint, thumbprint, false);
if (certificates.Count == 1)
{
return certificates[0];
}
}
finally
{
store.Close();
}
}
throw new ArgumentException(string.Format(
"A Certificate with Thumbprint '{0}' could not be located.",
thumbprint));
}
}
}
The certificate that you would want to use is the "Management Certificate". Here's the process for doing that:
Create a self-signed certificate on your computer (pfx file format). You may find this link useful: http://consultingblogs.emc.com/gracemollison/archive/2010/02/19/creating-and-using-self-signed-certificates-for-use-with-azure-service-management-api.aspx
Install that certificate in your local certificate store (preferably CurrentUser\My).
Export that certificate from your local certificate store on your computer in .cer file format.
Upload this certificate under management certificates section in the portal. To do so, login into Windows Azure portal (https://manage.windowsazure.com) and then click on "SETTINGS" tab and then click on "UPLOAD" button to choose and upload this file.
A few things to keep in mind:
You can have as many as 10 management certificates per subscription.
If you want your colleagues to use the same certificate, please share the pfx file created in step 1 and have them install the certificate in the certificate store of their local computer. Please don't give them .cer file created in step 3 as it does not have certificate's private data.
Hope this helps.

Resources