Как я могу получить подпись объекта X509Certificate2, используя C#?

Мне нужно получить подпись и алгоритм, используемый для создания этой подписи из сертификата с C#.

Могу ли я сделать это? Если да, то как?

3 ответа

Решение

Я разрабатываю сейчас приложение с аналогичным функционалом. И я действительно разочарован, почему Microsoft не добавила свойство Signature в класс X509Certificate2

Я знаю, как сделать это с помощью Bouncycastle

Возьми это оттуда http://www.bouncycastle.org/csharp/

Затем добавьте код

using System;
using System.Security.Cryptography.X509Certificates;
using bcrypto = Org.BouncyCastle.X509;

,

var cert = new X509Certificate2("c:\\temp\\0c50000343119659.cer");
var certParser = new bcrypto.X509CertificateParser();
var privateCertBouncy = certParser.ReadCertificate(cert.GetRawCertData());
var xx = privateCertBouncy.GetSignature();
Array.Reverse(xx);
//Signature
Console.WriteLine(BitConverter.ToString(xx));
//algorithm
Console.WriteLine(privateCertBouncy.SigAlgName);
Console.ReadLine();

Вам придется прибегнуть к Bouncy Castle,

https://github.com/bcgit/bc-csharp/blob/master/crypto/src/x509/X509Certificate.cs#L240

Его класс X509Certificate предоставляет вам доступ к этому свойству.

Вы можете использоватьAsnDecoderнаряду с информацией о структуре X509 v3, найденной в RFC3280, раздел 4.1. Сравните вывод этой функции сopenssl x509 -noout -text -in <pem file>

      /// <summary>
/// RFC3280 Section 4.1
/// Depth 1 of the X509 v3 cert is
/// Certificate  ::=  SEQUENCE  {
///     tbsCertificate TBSCertificate,
///     signatureAlgorithm   AlgorithmIdentifier,
///     signatureValue BIT STRING
/// }
///
/// https://www.rfc-editor.org/rfc/rfc3280#section-4.1
/// </summary>
public static byte[] Signature(this X509Certificate2 certificate)
{
    var signedData = certificate.RawDataMemory;
    AsnDecoder.ReadSequence(
        signedData.Span,
        AsnEncodingRules.BER,
        out var offset,
        out var length,
        out _
    );

    var certificateSpan = signedData.Span[offset..(offset + length)];
    AsnDecoder.ReadSequence(
        certificateSpan,
        AsnEncodingRules.BER,
        out var tbsOffset,
        out var tbsLength,
        out _
    );

    var offsetSpan = certificateSpan[(tbsOffset + tbsLength)..];
    AsnDecoder.ReadSequence(
        offsetSpan,
        AsnEncodingRules.BER,
        out var algOffset,
        out var algLength,
        out _
    );

    return AsnDecoder.ReadBitString(
        offsetSpan[(algOffset + algLength)..],
        AsnEncodingRules.BER,
        out _,
        out _
    );
}
Другие вопросы по тегам