代码之家  ›  专栏  ›  技术社区  ›  Jeff Dege

为什么某些证书的Request.ClientCertificate为空,而其他证书则为空?

  •  0
  • Jeff Dege  · 技术社区  · 7 年前

    我正在尝试构建一个AuthorizeAttribute,它要求HTTPRequest包含指定的客户端证书。

    我在VS2015中运行了一个测试webapi项目,在本地IIS(而不是iisexpress)上运行的站点上进行调试,配置了https,并将SSL设置为允许客户端证书。

    我很确定它的设置是正确的,因为它对我创建的一个证书工作得很好。

    我的属性很简单:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class KtRequireClientCertAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            byte[] cert = HttpContext.Current.Request.ClientCertificate.Certificate;
            // if the ClientCertificate is empty, pass null
            X509Certificate2 suppliedCert = cert.Any() ? new X509Certificate2(cert) : null;
    
            if (suppliedCert != null && isExpectedCert(suppliedCert)
                return;
    
            base.OnAuthorization(actionContext);
        }
    }
    

    我的问题是,这对我上周按照安德拉斯的指示创建的一个证书很有效。

    Certificate是一个字节[],包含808个元素,X509Certificate2构造正确,我的验证逻辑工作正常。

    但是对于我今天尝试创建的每个证书,HttpContext.Current.Request.ClientCertificate.certificate都是空的。

    MAKECERT.EXE -ic DevRootCertificate.cer -iv DevRootCertificate.pvk -pe -sv testclientcert.pvk -a sha1 -n "CN=testclientcert" -len 2048 -b 01/01/2015 -e 01/01/2030 -sky exchange testclientcert.cer -eku 1.3.6.1.5.5.7.3.2
    

    我的测试客户端应用程序很简单:

    using (var requestHandler = new WebRequestHandler())
    {
        var certificate = new X509Certificate2(certificateFile);
        requestHandler.ClientCertificates.Add(certificate);
    
        var url = new Uri(baseUrl);
        using (var client = new HttpClient(requestHandler){BaseAddress = url})
        {
            var response = client.GetAsync(endPoint).Result;
            response.EnsureSuccessStatusCode();
    
            var content = response.Content.ReadAsStringAsync().Result;
    
            Console.Out.WriteLine(JToken.Parse(content).ToString(Formatting.Indented));
        }
    }
    

    问题是为什么一个证书被传递给属性而另一个没有?


    其他信息:

    我在同一台服务器上运行同一个客户端,在本地计算机上的IIS上运行。网站配置为接受但不要求客户端证书。

    运行测试和不运行测试的唯一区别是从哪个.cer文件加载证书。

    我不确定有效的证书是否有私钥,但有效的文件是.cer,而不是.pfx。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Jeff Dege    7 年前

    第一个问题

    然后您需要在运行Web服务器的机器的机器存储中执行相同的操作。客户机和服务器都需要将根证书视为可信的权威,否则它们将不会对其签署的证书进行一致。

    一个有效的是一个.cer文件,那么为什么其他的.cer文件无效呢?

    当然是私钥。

    但是,你说,.cer文件没有私钥。是的,他们没有。但是为我工作的.cer文件是从用户存储导出的。

    我将.pfx文件导入到我的用户存储中,然后将其导出到.cer文件中。

    当我的客户机加载exported.cer文件时,它知道私钥是有效的,因为它在用户存储中,所以它不需要在创建X509Certificate2对象时提供密码。

    当我尝试对不在用户存储中的证书执行相同的操作时,使用.cer文件不起作用。如果我提供了密码,使用.pfx文件就可以了。

    var certificate = new X509Certificate2("testcert.pfx", "Password1");