加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 强制HttpWebRequest发送客户端证书

发布时间:2020-12-15 23:48:38 所属栏目:百科 来源:网络整理
导读:我有一个p12证书,我以这种方式加载它: X509Certificate2 certificate = new X509Certificate2(certName,password,X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); 它是正确加载的,实际上如果我
我有一个p12证书,我以这种方式加载它:

X509Certificate2 certificate = new X509Certificate2(certName,password,X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet |
        X509KeyStorageFlags.Exportable);

它是正确加载的,实际上如果我做了certificate.PrivateKey.ToXmlString(true);它返回一个完整的xml而没有错误.
但如果我这样做:

try
{
    X509Chain chain = new X509Chain();
    var chainBuilt = chain.Build(certificate);
    Console.WriteLine("Chain building status: "+ chainBuilt);

    if (chainBuilt == false)
        foreach (X509ChainStatus chainStatus in chain.ChainStatus)
            Console.WriteLine("Chain error: "+ chainStatus.Status);
}
catch (Exception ex)
{
    Console.WriteLine(ex);
}

它写道:

Chain building status: False
Chain error: RevocationStatusUnknown 
Chain error: OfflineRevocation

所以当我这样做时:

ServicePointManager.CheckCertificateRevocationList = false;
    ServicePointManager.ServerCertificateValidationCallback = (a,b,c,d) => true;
    ServicePointManager.Expect100Continue = true;
    Console.WriteLine("connessione a:" + host);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(host);
    req.PreAuthenticate = true;
    req.AllowAutoRedirect = true;
    req.ClientCertificates.Add(certificate);
    req.Method = "POST";
    req.ContentType = "application/x-www-form-urlencoded";
    string postData = "login-form-type=cert";
    byte[] postBytes = Encoding.UTF8.GetBytes(postData);
    req.ContentLength = postBytes.Length;
    Stream postStream = req.GetRequestStream();
    postStream.Write(postBytes,postBytes.Length);
    postStream.Flush();
    postStream.Close();

    WebResponse resp = req.GetResponse();

服务器说证书没有发送/有效.

我的问题是:

>即使链构建错误,我怎么能发送证书?
>还有另一个类发布证书,在发送之前不检查证书验证?

非常感谢.
安东尼

解决方法

我解决了这个问题,重点是P12文件(作为PFX)包含多于1个证书,因此必须以这种方式加载:

X509Certificate2Collection certificates = new X509Certificate2Collection();
certificates.Import(certName,X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

并以这种方式添加到HttpWebRequest:request.ClientCertificates = certificates;

谢谢大家的支持.

完整的示例代码

string host = @"https://localhost/";
string certName = @"C:tempcert.pfx";
string password = @"password";

try
{
    X509Certificate2Collection certificates = new X509Certificate2Collection();
    certificates.Import(certName,X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

    ServicePointManager.ServerCertificateValidationCallback = (a,d) => true;
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(host);
    req.AllowAutoRedirect = true;
    req.ClientCertificates = certificates;
    req.Method = "POST";
    req.ContentType = "application/x-www-form-urlencoded";
    string postData = "login-form-type=cert";
    byte[] postBytes = Encoding.UTF8.GetBytes(postData);
    req.ContentLength = postBytes.Length;

    Stream postStream = req.GetRequestStream();
    postStream.Write(postBytes,postBytes.Length);
    postStream.Flush();
    postStream.Close();
    WebResponse resp = req.GetResponse();

    Stream stream = resp.GetResponseStream();
    using (StreamReader reader = new StreamReader(stream))
    {
        string line = reader.ReadLine();
        while (line != null)
        {
            Console.WriteLine(line);
            line = reader.ReadLine();
        }
    }

    stream.Close();
}
catch(Exception e)
{
    Console.WriteLine(e);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读