I am trying to generate a client assertion from a X509Certificate2
(here is the documentation). The fact is that my code is working perfectly when I get the certificate
from a file as follows :
string signinCertPath = Path.Combine(Directory.GetCurrentDirectory(), "Cert", "anAwesomeCertificate.pfx");
X509Certificate2 certificate = new X509Certificate2(signinCertPath, "MySuperCertificatePassword", X509KeyStorageFlags.EphemeralKeySet);
string clientAssertion = GenerateClientAssertion(certificate, tenantId, clientId); //clientAssertion handles the value I am looking for.
Here is the GenerateClientAssertion method, that I've copied from the MSAL documentation :
private string GenerateClientAssertion(X509Certificate2 certificate, string tenantId, string clientId)
{
// Get the RSA with the private key, used for signing.
var rsa = certificate.GetRSAPrivateKey();
//alg represents the desired signing algorithm, which is SHA-256 in this case
//x5t represents the certificate thumbprint base64 url encoded
var header = new Dictionary<string, string>()
{
{ "alg", "RS256"},
{ "typ", "JWT" },
{ "x5t", Base64UrlEncode(certificate.GetCertHash()) }
};
var claims = GetClaims(tenantId, clientId);
var headerBytes = JsonConvert.SerializeObject(header);
var claimsBytes = JsonConvert.SerializeObject(claims);
string token = Base64UrlEncode(Encoding.UTF8.GetBytes(Newtonsoft.Json.Linq.JObject.FromObject(header).ToString())) + "." + Base64UrlEncode(Encoding.UTF8.GetBytes(Newtonsoft.Json.Linq.JObject.FromObject(claims).ToString()));
string signature = Base64UrlEncode(rsa.SignData(Encoding.UTF8.GetBytes(token), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
string signedClientAssertion = string.Concat(token, ".", signature);
return signedClientAssertion;
}
The problem is that I am not able to access the certificate file in real conditions, that is why I copied it in a byte[]
and try to do the same thing by creating the certificate with the byte[]
, like that :
X509Certificate2 certificate = new X509Certificate2(variables.cert, "MySuperCertificatePassword", X509KeyStorageFlags.EphemeralKeySet); //variables.cert is the byte[]
string clientAssertion = GenerateClientAssertion(certificate, tenantId, clientId);
And here comes the issue : my code throw me an error as the rsa
variable is not set to an instance of an object, meaning that I am not getting the certificate private key.
So does anybody know how I can get this private key?
Any contribution would be nice. Thanks by advance.