C# 从 CA 独立获取证书



我有一个独立的 CA,我需要使用 C# 按证书序列号搜索来获取完整的证书 base64 字符串。

已尝试使用 X509Store,尝试使用 CA 名称、主机名\CA 名称以及所有存储名称和存储位置可能的变体

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,此方法返回信息,但它不是完整的证书,当我从CA手动导出时,字符串不相等。

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);
}

根本没有成功。

问题是您正在请求包含完整响应的属性FR_PROP_FULLRESPONSE(IIRC,PKCS#7 消息)。相反,您应该仅请求颁发的证书属性:FR_PROP_ISSUEDCERTIFICATE

顺便说一句,不需要ICertRequest接口调用。为什么不在ICertView接口调用中将RawCertificate列放入结果列列表中,然后获取结果?

使用此代码解决

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;
}

相关内容

  • 没有找到相关文章

最新更新