【问题标题】:.Net client authentication setup using HttpWebRequest.Net 客户端身份验证设置使用 HttpWebRequest
【发布时间】:2016-10-14 00:55:51
【问题描述】:

这更多的是关于如何让 HttpWebRequest 工作,或者即使 HttpWebRequest 是正确的实现。在过去的几年里,我让我的 C# 和 .Net 技能失效了,所以我希望我能原谅。

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

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

服务器是 Java,这些证书采用 .jks 格式的信任库和密钥库。我将它们提取到 .pem 文件中。

所以,我在 C# 客户端失败了,所以我想我会写一点 Python sn-p 以确保至少服务器端按预期工作。二十分钟后,我正在发布安全帖子。这是代码:

# 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 done 之后。

【问题讨论】:

  • 您在 catch 块上遇到的异常究竟是什么?
  • {"请求被中止:无法创建 SSL/TLS 安全通道。"} 我遇到过,有时会通过这个,然后在服务器端出现错误。这两天我一直在搞砸。
  • 您是否尝试过设置安全协议? System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; 因为在你的 python 代码中你已经指定了ssl.SSLContext(ssl.PROTOCOL_TLS)
  • 已添加。没运气。我认为缺少的东西相当于 Python load_cert_chain。
  • 我不是证书专家,但answer 可能会帮助您。涉及X509Chain Class

标签: c# authentication post client httpwebrequest


【解决方案1】:

好的,我认为我在原版中非常接近,但我是这样解决的:

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

“trustore”文件是一个 .p12,包含上面列出的证书。可以通过 keytool 和 openssl 从 .jks 信任库创建 .p12 信任库。那里有很多关于如何做到这一点的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    相关资源
    最近更新 更多