使用HttpWebRequest的.Net客户端身份验证设置 [英] .Net client authentication setup using HttpWebRequest

查看:174
本文介绍了使用HttpWebRequest的.Net客户端身份验证设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是有关如何使HttpWebRequest正常工作甚至HttpWebRequest是正确的实现的更多信息.在过去的几年中,我已经使我的C#和.Net技能失效,所以希望对此我可以原谅.

我试图访问一个需要客户端身份验证的安全Web服务.我有四个证书可以解决这个问题.

•根证书 •中级根证书 •设备证书 •私钥

该服务器是Java,这些证书以trustore和keystore的.jks格式提供.我将它们拉入.pem文件.

因此,我在C#客户端上失败了,所以我想写一点Python代码段以确保至少服务器端按预期工作.二十分钟后,我正在发布安全信息.这是代码:

# Keys
path = "C:\\path\\"
key = path + "device.pem"
privkey = path + "device_privkey.pem"
CACerts = path + "truststore.concat" # root & intermediate cert


def post():
    url = "/url"
    headers = {'Content-Type': 'application/xml'}

    ## This section is HTTPSConnection

    context = ssl.SSLContext(ssl.PROTOCOL_TLS)
    context.verify_mode = ssl.CERT_OPTIONAL

    context.load_cert_chain(key, privkey, password='password')
    context.verify_mode = ssl.CERT_NONE
    context.load_verify_locations(CACerts)

    conn = http.client.HTTPSConnection(host, port=8080, context=context)
    conn.request("POST", url, registrationBody, headers)

    response = conn.getresponse()

    regresp = response.read()

concat证书是根证书和中间证书的串联.

你和我在一起吗?

现在让我的C#/.Net头疼.

这是我的尝试.我显然不知道我在这里做什么.

    public async Task POSTSecure(string pathname, string body)
    {
        string path = "C:\\path";
        string key = path + "device.pem";
        string privkey = path + "device_privkey.pem";
        string CACerts1 = path + "vtn_root.pem";
        string CACerts2 = path + "vtn_int.pem";

        try
        {
            // Create certs from files
            X509Certificate2 keyCert = new X509Certificate2(key);
            X509Certificate2 rootCert = new X509Certificate2(CACerts1);
            X509Certificate2 intCert = new X509Certificate2(CACerts2);

            HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("https://" + host + ":" + port + pathname);
            ServicePoint currentServicePoint = request.ServicePoint;

            // build the client chain?
            request.ClientCertificates.Add(keyCert);
            request.ClientCertificates.Add(rootCert);
            request.ClientCertificates.Add(intCert);

            Console.WriteLine("URI: {0}", currentServicePoint.Address);

            // This validates the server regardless of whether it should
            request.ServerCertificateValidationCallback = ValidateServerCertificate;

            request.Method = "POST";
            request.ContentType = "application/xml";
            request.ContentLength = body.Length;

            using (var sendStream = request.GetRequestStream())
            {
                sendStream.Write(Encoding.UTF8.GetBytes(body), 0, body.Length);
            }

            var response = (HttpWebResponse)request.GetResponse();
        }
        catch (Exception e)
        {
            Console.WriteLine("Post error.");
        }
    }

感谢您的帮助或指向不错的教程的指针.

更多信息.在服务器端,调试指向空的客户端证书链.这是在报告serverhello完成之后.

解决方案

好吧,我认为我与原著很接近,但是我是这样解决的:

            request.ClientCertificates = new X509Certificate2Collection(
                                new X509Certificate2(
                                    truststore,
                                    password));

"trustore"文件是一个.p12文件,其中包含上面列出的证书.可以通过keytool和openssl从.jks信任库创建.p12信任库.许多有关如何执行此操作的信息.

This is more about how to get HttpWebRequest to work or even if HttpWebRequest is the right implementation. I've let my C# and .Net skill lapse the past few year, so I hope I can be forgiven for that.

I trying to hit a secure web service that requires client authentication. I have four certs to hit this with.

• Root Certificate • Intermediate Root Certificate • Device Certificate • Private Key

The server is Java and these certs are in .jks form trustore and keystore. I pulled them into .pem files.

So, I failed on the C# client side, so I thought I'd write a little Python snippet to make sure at least the server side is working as expected. Twenty minutes later, I'm making secure posts. Here's that code:

# Keys
path = "C:\\path\\"
key = path + "device.pem"
privkey = path + "device_privkey.pem"
CACerts = path + "truststore.concat" # root & intermediate cert


def post():
    url = "/url"
    headers = {'Content-Type': 'application/xml'}

    ## This section is HTTPSConnection

    context = ssl.SSLContext(ssl.PROTOCOL_TLS)
    context.verify_mode = ssl.CERT_OPTIONAL

    context.load_cert_chain(key, privkey, password='password')
    context.verify_mode = ssl.CERT_NONE
    context.load_verify_locations(CACerts)

    conn = http.client.HTTPSConnection(host, port=8080, context=context)
    conn.request("POST", url, registrationBody, headers)

    response = conn.getresponse()

    regresp = response.read()

The concat certificate is the concatenation of the root and intermediate certificates.

Are you with me?

Now to my C#/.Net headache.

This my attempt. I clearly don't know what I'm doing here.

    public async Task POSTSecure(string pathname, string body)
    {
        string path = "C:\\path";
        string key = path + "device.pem";
        string privkey = path + "device_privkey.pem";
        string CACerts1 = path + "vtn_root.pem";
        string CACerts2 = path + "vtn_int.pem";

        try
        {
            // Create certs from files
            X509Certificate2 keyCert = new X509Certificate2(key);
            X509Certificate2 rootCert = new X509Certificate2(CACerts1);
            X509Certificate2 intCert = new X509Certificate2(CACerts2);

            HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("https://" + host + ":" + port + pathname);
            ServicePoint currentServicePoint = request.ServicePoint;

            // build the client chain?
            request.ClientCertificates.Add(keyCert);
            request.ClientCertificates.Add(rootCert);
            request.ClientCertificates.Add(intCert);

            Console.WriteLine("URI: {0}", currentServicePoint.Address);

            // This validates the server regardless of whether it should
            request.ServerCertificateValidationCallback = ValidateServerCertificate;

            request.Method = "POST";
            request.ContentType = "application/xml";
            request.ContentLength = body.Length;

            using (var sendStream = request.GetRequestStream())
            {
                sendStream.Write(Encoding.UTF8.GetBytes(body), 0, body.Length);
            }

            var response = (HttpWebResponse)request.GetResponse();
        }
        catch (Exception e)
        {
            Console.WriteLine("Post error.");
        }
    }

Thanks for any help or a pointer to a decent tutorial.

[Edit] More info. On the server side, the debugging points to an empty client certificate chain. This is right after it reports serverhello done.

解决方案

Okay, I think I was pretty close in the original, but I solved it this way:

            request.ClientCertificates = new X509Certificate2Collection(
                                new X509Certificate2(
                                    truststore,
                                    password));

The "trustore" file is a .p12 containing the certificates listed above. The .p12 truststore can be created from the .jks truststore through keytool and openssl. Lots of info out there on how to do that.

这篇关于使用HttpWebRequest的.Net客户端身份验证设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆