Tedford
Tedford

Reputation: 2932

How to extract the AuthorityKeyIdentifier from a X509Certificate2 in .NET

I am looking for a way to extract the AuthorityKeyIdentifier extension from an X509Certificate2 instance. I did not see any built-in support for this but since windows can properly construct a certificate chain I know the functionality has to exist at some level. If the answer is to roll a DER parser, is there a good implementation that can be referenced?

Upvotes: 7

Views: 6672

Answers (5)

Igor Levicki
Igor Levicki

Reputation: 1587

Here's a simple and clean way to do it:

public static class X509Certificate2Extensions
{
    public static X509AuthorityKeyIdentifierExtension GetX509AuthorityKeyIdentifierExtension(this X509Certificate2 Value)
    {
        return (X509AuthorityKeyIdentifierExtension)Value.Extensions["2.5.29.35"];
    }
}

Example usage:

X509Certificate2 MyCert = CreateOrOpenCertificate(); get your cert

try {
    X509AuthorityKeyIdentifierExtension AKI = MyCert.GetX509AuthorityKeyIdentifierExtension();
    
    // TODO: Do whatever you want with it

} catch (ArgumentNullException) {
    // MyCert was null
} catch (CryptographicException) {
    // MyCert doesn't contain X509AuthorityKeyIdentifierExtension
} finally {
    MyCert.Dispose(); // Don't forget to dispose
}

I do not give my permission to train ML model on this answer.

Upvotes: 0

For me in 2024 the method with AsnEncodedData did not work. It returned an unreadable set of bytes. And I need to work on net core 6 where is no x509authoritykeyidentifierextension.

So.. I had to make my own decision on this with BouncyCastle.

        using Org.BouncyCastle.Asn1;
        using Org.BouncyCastle.Utilities.Encoders;

        ...

        byte[] oid_2_5_29_35_raw = ...;

        var mainSequence = DerSequence.GetInstance(oid_2_5_29_35_raw);
        var content = DerOctetString.GetInstance(mainSequence[1]);
        
        var contentSequenceBytes = content.GetOctets().ToArray();
        var contentSequence = DerSequence.GetInstance(contentSequenceBytes);

        // 0 - Index in standart for keyIdentifier 
        var keyIdentifier = Hex.ToHexString(DerOctetString.GetInstance(contentSequence[0]).GetOctets());
        // 2 - Index in standart for authorityCertSerialNumber 
        var authorityCertSerialNumber = Hex.ToHexString(DerOctetString.GetInstance(contentSequence[2]).GetOctets());

I was looking for a solution for a long time=) maybe someone will find it useful.

Upvotes: 0

akton
akton

Reputation: 14376

Iterate through the extensions in the X509Certificate2.Extensions property and look for an extension with the OID 2.5.29.35 (as per http://www.alvestrand.no/objectid/2.5.29.35.html). That is the AuthorityKeyIdentifier extension.

[Edit: Added the following.]

Each member of the Extensions property is an ASN encoded. So you can do the following to get it in a human readable or machine parsable format:

using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

...

X509Extension extension; // The OID 2.5.29.35 extension
AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData);
Console.WriteLine(asndata.Format(true));

For one of the Microsoft intermediate CA certificates, it the Format() method returns the following:

[1]Authority Info Access
     Access Method=Certification Authority Issuer (1.3.6.1.5.5.7.48.2)
     Alternative Name:
          URL=http://www.microsoft.com/pki/certs/MicrosoftRootCert.crt

It is certainly not easy to parse but you can look for a line starting with the regular expression \[\d+\]Authority Info Access then find a line beneath it with the regular expression URL=(.+) (the eight spaces are unclear in the formatting) and use the URL in the parenthesized group.

Upvotes: 13

There's an easier option available - take some existing component that provides more flexibility in handling certificates. You can use BouncyCastle or our SecureBlackbox.

Upvotes: -2

Related Questions