2017-01-13 4 views
0

У меня есть автономный CA, и мне нужно получить полную строку base64 сертификата, используя поиск C# по серийному номеру сертификата.C# Получить сертификат из CA автономный

Уже пытались использовать X509Store, попытался с именем CA, CA-имя \ имя хоста, и все StoreName и StoreLocation возможные варианты

store = new X509Store("my-ca"); 
store.Open(OpenFlags.ReadOnly); 
ret += "Count: " + store.Certificates.Count; 
foreach (X509Certificate2 cert in store.Certificates) 
{ 
    ret += "cert.SerialNumber: " + cert.SerialNumber; 
} 

А также попытался с CCertView/CCertRequest, этот метод возвращает информацию, но это а не полный сертификат, строка не равна, когда я вручную экспортирую из ЦС.

public string GetCertificateBase64Original(string certificateSerialNumber) 
{ 
    string certificateBase64 = string.Empty; 

    try 
    { 
     CCertView certView = new CCertViewClass(); 
     certView.OpenConnection(this.nameCA); 

     certView.SetResultColumnCount(2); 

     int requestIDColumnIndex = certView.GetColumnIndex(0, "RequestID"); 
     int certificateSerialNumberColumnIndex = certView.GetColumnIndex(0, "SerialNumber"); 

     certView.SetResultColumn(requestIDColumnIndex); 
     certView.SetResultColumn(certificateSerialNumberColumnIndex); 

     object objSerialNumber = certificateSerialNumber; 

     certView.SetRestriction(certificateSerialNumberColumnIndex, CVR_SEEK_EQ, CVR_SORT_NONE, ref objSerialNumber); 

     IEnumCERTVIEWROW rowsEnum; 
     rowsEnum = certView.OpenView(); 

     IEnumCERTVIEWCOLUMN objCol; 
     rowsEnum.Reset(); 

     int requestID = 0; 

     while (rowsEnum.Next() != -1) 
     { 
      objCol = rowsEnum.EnumCertViewColumn(); 

      while (objCol.Next() != -1) 
      { 
       if (objCol.GetName() == "RequestID") 
       { 
        try 
        { 
         requestID = SafeConvert.ToInt(objCol.GetValue(PROPTYPE_STRING)); 
        } 
        catch 
        { 
        } 
       } 
      } 
     } 

     if (requestID > 0) 
     { 
      CCertRequest certRequest = new CCertRequest(); 

      certRequest.GetIssuedCertificate(this.nameCA, requestID, certificateSerialNumber); 

      certificateBase64 = SafeConvert.ToString(certRequest.GetFullResponseProperty(FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64)); 
     } 
    } 
    catch 
    { 
    } 

    return (certificateBase64); 
} 

Отсутствие успехов вообще.

+0

Пожалуйста, начните с чтения [просить] и размещения [MCVE] –

+0

Где ваш код работает по отношению к СА? – bartonjs

+0

Добавлены образцы кода. @CamiloTerevinto –

ответ

0

решаемые с помощью этого кода

https://blogs.msdn.microsoft.com/alejacma/2012/04/04/how-to-export-issued-certificates-from-a-ca-programatically-c/ https://blogs.msdn.microsoft.com/alejacma/2010/05/10/how-to-get-info-from-client-certificates-issued-by-a-ca-c/

public string GetCertificateBase64(string certificateSerialNumber) 
{ 
    string certificateBase64 = string.Empty; 

    try 
    { 
     // Variables 
     CERTADMINLib.CCertView certView = null; 
     CERTADMINLib.IEnumCERTVIEWROW certViewRow = null; 
     CERTADMINLib.IEnumCERTVIEWCOLUMN certViewColumn = null; 
     int iColumnCount = 0; 
     object objValue = null; 

     // Connecting to the Certificate Authority 
     certView = new CERTADMINLib.CCertView(); 
     certView.OpenConnection(this.nameCA); 

     // Get a column count and place columns into the view 
     iColumnCount = certView.GetColumnCount(0); 
     certView.SetResultColumnCount(iColumnCount); 

     // Place each column in the view. 
     for (int x = 0; x < iColumnCount; x++) 
     { 
      certView.SetResultColumn(x); 
     } 

     int certificateSerialNumberColumnIndex = certView.GetColumnIndex(0, "SerialNumber"); 
     object objSerialNumber = certificateSerialNumber; 
     certView.SetRestriction(certificateSerialNumberColumnIndex, CVR_SEEK_EQ, CVR_SORT_NONE, ref objSerialNumber); 

     // Open the View and reset the row position 
     certViewRow = certView.OpenView(); 
     certViewRow.Reset(); 

     // Enumerate Row and Column Information 

     // Rows (one per cert) 
     for (int x = 0; certViewRow.Next() != -1; x++) 
     { 
      // Columns with the info we need 
      certViewColumn = certViewRow.EnumCertViewColumn(); 
      while (certViewColumn.Next() != -1) 
      { 
       switch (certViewColumn.GetDisplayName()) 
       { 
        // Binary Certificate 
        case "Binary Certificate": 
         objValue = certViewColumn.GetValue(CV_OUT_BASE64); 
         if (objValue != null) 
         { 
          certificateBase64 = objValue.ToString(); 
         } 
         break; 

        default: 
         break; 
       } 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     certificateBase64 += Environment.NewLine + "ex: " + ex.Message; 
    } 

    return certificateBase64; 
} 
0

Проблема заключается в том, что вы запрашиваете свойство FR_PROP_FULLRESPONSE, которое содержит полный ответ (IIRC, сообщение PKCS # 7). Вместо этого вы должны запросить только выданное свойство сертификата: FR_PROP_ISSUEDCERTIFICATE.

BTW ICertRequest интерфейс звонок не требуется. Почему бы не поставить столбец RawCertificate в список столбцов результатов в ICertView интерфейсных вызовах, а затем взять результат?

+0

Это код 2009 года, который никогда не работал, и кто-то хочет использовать его сейчас, я просто пытаюсь заставить его работать, я не оригинал, поэтому я не знаю, почему он что-то сделал. И этот код seens запускается только на сервере 2003 года, я не знаю почему, но это не работает на моем сервере 2012 + CA. Попробуйте изменить FR_PROP_FULLRESPONSE для FR_PROP_ISSUEDCERTIFICATE (private const int FR_PROP_ISSUEDCERTIFICATE = 11;) –

+0

Попробует использовать objCol.GetName() == "RawCertificate" –

+0

Не забудьте добавить этот столбец в список выходных столбцов. – Crypt32

Смежные вопросы