问题
I uploaded a Certificate to Azure KeyVault and obtained "all" access to it using an application registered into the Active Directory. That all works fine. Now I need to load the obtained key into an X509Certificate to be able to use it as a client certificate for calling a 3rdparty legacy SOAP webservice. As far as I know I can only use a X509Certificate to call that webservice.
It does not matter if I upload it as a Key or Secret? I have tried both.
var clientId = "...."
var clientSecret = "...."
..
var token = authenticationContext.GetAccessToken(resource, adCredential);
var keyClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(token));
KeyBundle key = keyClient.GetKeyAsync("https://mycertifcates.vault.azure.net/keys/MyCertificate/123456789");
So far so good, I got a KeyBundle as a result and it seems like I can convert it to a Base64String, but whatever I try I end up with exceptions :(
1st attempt I tried:
var publicKey = Convert.ToBase64String(key.Key.N);
var cert = X509Certificate.FromBase64String(publicKey);
System.Security.Cryptography.CryptographicException {"Cannot find the requested object.\r\n"}
Ahhhh
2nd attempt, loading it into an RSACryptoServiceProvider, but what to do with that? Results into the same exception and I'm not even able to get the private key if I want to
var rsaCryptoProvider = new RSACryptoServiceProvider();
var rsaParameters = new RSAParameters()
{
Modulus = key.Key.N,
Exponent = key.Key.E
};
rsaCryptoProvider.ImportParameters(rsaParameters);
var cspBlob = rsaCryptoProvider.ExportCspBlob(false);
// what to do with the cspBlob ?
var publicKey = Convert.ToBase64String(cspBlob);
No private key as well, the public key is different. Ofcourse this does not work either.
3rd attempt
I uploaded it as a Secret Certificate ContentType using the management portal.
var secret = helper.GetSecret("https://myCertificate.vault.azure.net/secrets/MyCertificate/1234567890");
var value = secret.Value;
// Now I got the secret.. works flawless
// But it crash with the same exception at .Import
var exportedCertCollection = new X509Certificate2Collection();
exportedCertCollection.Import(Convert.FromBase64String(value));
var cert2 = exportedCertCollection.Cast<X509Certificate2>().Single(s => s.HasPrivateKey);
System.Security.Cryptography.CryptographicException {"Cannot find the requested object.\r\n"}
Any suggestion is welcome.
I need the pfx including private key, looking at the tracelog
ystem.Net Information: 0 : [37880] SecureChannel#23107755 - Left with 1 client certificates to choose from. System.Net Information: 0 : [37880] SecureChannel#23107755 - Trying to find a matching certificate in the certificate store. System.Net Information: 0 : [37880] SecureChannel#23107755 - Locating the private key for the certificate: [Subject]
回答1:
To answer my own question (I asked it too quickly I guess)
It turns out that this question was in fact a duplicate, but I did not understand it at first. The fact is that the Azure Management Portal is limited. For now uploading a certificate can only be done by using a powershell (or other code for that matter).
https://stackoverflow.com/a/34186811/578552
The 3rd attempt code works fine for the X509Certificate2
var secret = helper.GetSecret("https://myCertificate.vault.azure.net/secrets/MyCertificate/1234567890");
var exportedCertCollection = new X509Certificate2Collection();
exportedCertCollection.Import(Convert.FromBase64String(secret.Value));
var cert2 = exportedCertCollection.Cast<X509Certificate2>().Single(s => s.HasPrivateKey);
来源:https://stackoverflow.com/questions/40151705/azure-keyvault-how-to-load-x509certificate