Oppositional
Oppositional

Reputation: 11211

How do you retrieve the X.509 certificate that was used to construct a X509AsymmetricSecurityKey?

You can construct a X509AsymmetricSecurityKey from a X509Certificate2 instance using the X509AsymmetricSecurityKey(X509Certificate2) constructor; but can get the X509Certificate2 instance from the security key?

As a parallel example, the InMemorySymmetricSecurityKey class exposes a GetSymmetricKey() method that can be used to retrieve the symmetric key.

I had hoped to see an equivalent method like GetCertificate() exposed by the X509AsymmetricSecurityKey class, but the closest method I see is GetAsymmetricAlgorithm(string algorithm, bool privateKey).

What I am really after is the ability to verify the digital signature of a message that was signed using the private key of the certificate, which means the signature is verified using the public key of the certificate.

Is there a way to verify the signature using the asymmetric algorithm of the security key?

Upvotes: 2

Views: 2163

Answers (3)

Visar
Visar

Reputation: 138

When you construct X509AsymmetricSecurityKey out of an X509Certificate2, the certificate instance reference is actually placed inside a private property named certificate on the key instance.

Your own answer satisfies your specific use case but not your question, the real answer to your question is:

there is no direct way, but you can do it by using reflection.

X509AsymmetricSecurityKey x509Key = ...

X509Certificate2 cert = typeof(X509AsymmetricSecurityKey).GetField("certificate", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(x509Key) as X509Certificate2;

Upvotes: 3

Oppositional
Oppositional

Reputation: 11211

While owlstead was correct that you cannot retrieve the X.509 certificate from the security key; what I should have indicated was that I was attempting to verify a digital signature of a JSON web token where the security key contained the public portion of the public-private key pair.

You can in fact use the security key to verify the signature. The following is an example of how to generally go about it:

var data        = {Get data that was signed as an array of bytes}
var signature   = {Get signature as an array of bytes}

// key variable is of type X509AsymmetricSecurityKey

using(var rsa = key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, false) as RSACryptoServiceProvider)
{
    if(rsa != null)
    {
        using(var halg = new SHA256CryptoServiceProvider())
        {
            if (!rsa.VerifyData(data, halg, signature))
            {
                throw new SecurityException("Signature is invalid.");
            }
        }
    }
}

Upvotes: 1

Maarten Bodewes
Maarten Bodewes

Reputation: 94058

X509AsymmetricSecurityKey is a component of X509Certificate2. You are asking if you can retrieve a car given a tire. X509 certificates contain a whole lot of additional information in addition to the public key stored within (issuer, serial number, key usage, effective date etc. etc.).

On the other hand, InMemorySymmetricSecurityKey does contain all the information of the symmetric key, so it is possible to retrieve the full key data using GetSymmetricKey(). Note that GetSymmetricKey() only returns a byte array, not a semantic object instance.

The only thing special about the Microsoft X509Certificate2 is that it is linked with the private key, which is not part of the X509 data format. The private key and the public key in the certificate are part of the same key pair. That's why the private key can be thought of as part of the X509 certificate. They are also often stored together, e.g. in the PKCS#12 data format. Personally I think it only confuses matters.

If you want to link certificates with private keys then you can use the modulus of the key pair. It's identical for the private key and the public key. In some cryptographic standards they use a hash over the modulus to do this. So you can create a map from the hash over the modulus to a certificate. If you got a private key, retrieve the modulus, calculate the hash, and find the certificate.

Upvotes: 0

Related Questions