在.Net Compact Framework中使用X509证书进行客户端身份验证HTTPRequest

问题描述:

我正在使用Windows Mobile 6,并且想与Apache网络服务器进行客户端身份验证。我在本地证书存储区中有一个证书,应该很简单:

I'm working in Windows Mobile 6 and would like to have client authentication when talking to a Apache webserver. I have a certificate in my local certificate store and it should be rather straightforward:

X509Store myStore = new X509Store("MY", StoreLocation.CurrentUser);
myStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificates = myStore.Certificates;
X509Certificate2 clientcertificate;
foreach (X509Certificate 2certificate in certificates) {
     clientcertificate = certificate; //omitted code to validate certificate
}
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(webPage);
req.AllowWriteStreamBuffering = true;
req.AllowAutoRedirect = false;
req.Method = "POST";
req.ContentType = "text/xml";
req.Accept = "text/xml";
req.ClientCertificates.Add(clientcertificate);
Stream stream = req.GetRequestStream();
stream.Write(buffer, 0, buffer.Length);
stream.Close();

只要我删除 req.ClientCertificates.Add(clientcertificate)行,此代码段就起作用。

This code segment works as long as I remove the "req.ClientCertificates.Add(clientcertificate)" line.

一旦插入,我会收到无法为SSL / TLS建立安全通道的信息。令人发疯的是,当我在常规.Net Framework中使用此确切代码时,它可以完美地传输证书。

Once that's inserted, I get a "Could not establish secure channel for SSL/TLS". Maddeningly enough, when I use this exact code in the regular .Net Framework it transmits the certificate perfectly.

有人知道在Compact Framework中是否可行?如果我不能出示用于客户端身份验证的X509证书,我应该采取什么其他方式来确保身份验证正确(我应该可以访问CAPI或其他Microsoft加密模块)

Does anyone know if this is possible in Compact Framework? If I can't present the X509Certificate for Client Authentication, what other ways should I pursue to ensure that authentication is proper (I should have access to CAPI or other Microsoft Cryptographic modules)

谢谢。

好消息:我解决了。事实证明,这与.Net Compact Framework无关。在3.5 CF中,只要可以访问X509证书,就支持HTTPWebRequest.ClientCertificates。

Good news: I solved it. It turned out not to have to do with the .Net Compact Framework. In 3.5 CF, HTTPWebRequest.ClientCertificates is supported as long as the X509 certificate can be accessed.

SSL握手失败的原因是由于服务器的信任问题副证书。我们的服务器证书是自签名的,并且我们使用为错误的URL签名的证书,因此应用程序正确地不会信任提供的服务器证书。为了进行测试,我们制定了信任所有证书策略,该策略将在生产中删除。

The reason why the SSL Handshake failed was because of a trust issue with the server side certificate. Our server certificates were self-signed and we used certificates that were signed for the wrong URL, so the application rightly wouldn't trust the provided server certificate. For testing purposes, we put in place a Trust All Certificates policy, which will be removed for the production.

sealed class AcceptAllCertificatePolicy : ICertificatePolicy
{
    private const uint CERT_E_UNTRUSTEDROOT = 0x800B0109;

    public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate
    certificate, WebRequest request, int certificateProblem)
    {
        // Just accept.
        return true;
    }
    /*public bool CheckValidationResult(ServicePoint sp,
    X509Certificate cert, WebRequest req, int problem)
    {
        return true;  
    }*/
}

在HTTPWebRequest之前引用

Referenced right before the HTTPWebRequest

System.Net.ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();

这解决了SSL / TLS安全通道的问题。

And this solves our problem with the SSL/TLS secure channel.