Задать вопрос

Как получить Public Key сертификата идентичный с выводу openssl?

да, звучит весьма глупо. но так и есть.
предположим есть у нас сертификат crt.cer в Base64
далее запускаю openssl x509 -in crt.cer -pubkey и на выходе получаю (например длиной 294 байта):
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvUihVNnWYpu3uJmcLy+PBecKu4ziVD7OIeZ/V+tJkXbc5+6OW8G+QDtJKuJkkuxGNLBNmLHbCyXsJ/US3kKkU7/7yK7jfWRNdqAKJdDTVxsWnxlo+/28ScGrAV6wK2bbK8GQBpsYRn1HKGCGceWIBCSqUfI7rwgwDnvqcW5PeivORd4+or5DdhgUMwiV5Vr2fvdcAiQR1CKgMphxO4+OmZ4khpB/HT/xS4FscvfFsSBLM37jBMrnhY5yNKPeHZB2eYvehnnw22NFHJNksa+vVFXL9aJcZWJc/bqqlhlhL8eLdYSR/KA006PSInW8yWtd4IFVKJ1Moa41gCUZL81voQIDAQAB

Затем тоже самое делаю в коде UWP приложения:
X509Certificate2 certificate = new X509Certificate2(certificateBlob);
var truePublicKey = Convert.ToBase64String(certificate.GetPublicKey());

на выходе нечто вроде этого (длиной уже 270 байт)
MIIBCgKCAQEAvUihVNnWYpu3uJmcLy+PBecKu4ziVD7OIeZ/V+tJkXbc5+6OW8G+QDtJKuJkkuxGNLBNmLHbCyXsJ/US3kKkU7/7yK7jfWRNdqAKJdDTVxsWnxlo+/28ScGrAV6wK2bbK8GQBpsYRn1HKGCGceWIBCSqUfI7rwgwDnvqcW5PeivORd4+or5DdhgUMwiV5Vr2fvdcAiQR1CKgMphxO4+OmZ4khpB/HT/xS4FscvfFsSBLM37jBMrnhY5yNKPeHZB2eYvehnnw22NFHJNksa+vVFXL9aJcZWJc/bqqlhlhL8eLdYSR/KA006PSInW8yWtd4IFVKJ1Moa41gCUZL81voQIDAQAB

Если присмотреться повнимательнее, то видно что во втором случае спереди отрезан кусок данных, а в остальном они идентичны.
Воспользовавшись онлайн декодером ASN1 данных можно заметить, что в C# приложении "отрезано все лишнее", но такой вариант мне не подходит. Возможно ли как-нибудь получить идентичный openssl результат? (желательно без написания своего ASN кодера/декодера). Что только не пробовал - не получается( А ключ нужен именно как в первом варианте, т.к. дальше считается хеш

PS: С использованием Chillkat либы мне удалось получить нужный ключ, но она не бесплатная. Для моих целей не подходит.
  • Вопрос задан
  • 1043 просмотра
Подписаться 3 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
@llexus Автор вопроса
Алексей Немиро , спасибо за подсказку! Примерно то и получилось. Может кому пригодится:
public static IEnumerable<string> GetPublicKeysList(IReadOnlyList<Certificate> serverCertificates)
        {
            for (var i = 0; i < serverCertificates.Count; i++)
            {
                string publicKey = null;
                try
                {
                    var certificate = new X509Certificate2(serverCertificates[0].GetCertificateBlob().ToArray());
                    var ms = new MemoryStream(certificate.RawData);
                    using (var reader = new BerReader(ms))
                    {
                        var asnCert = reader.ReadToEnd(true);
                        var pkNode = asnCert.ChildNodes[0].ChildNodes[0].ChildNodes[6]; // тут лежит сам ключ
                        byte[] pkBuffer = new byte[pkNode.Length + (pkNode.DataOffsetToStream - pkNode.StartPosition)];
                        ms.Seek(pkNode.StartPosition, SeekOrigin.Begin);
                        ms.Read(pkBuffer, 0, pkNode.Length + (int)(pkNode.DataOffsetToStream - pkNode.StartPosition)); // чтобы не потерять последние 4 байта
                        publicKey = Convert.ToBase64String(pkBuffer);
                    }
                }
                catch (Exception ex)
                {
                    throw new SecurityException($"Cant get public key {ex.Message}");
                }
                yield return publicKey;
            }
        }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы