WebRequest 不发送客户端证书

2023-11-25

我正在为 REST API 编写一个客户端,为了对 API 进行身份验证,我必须使用提供给我的证书。

这段代码如下:

public string GetCustomer(int custId)
{
X509Certificate2 Cert = new X509Certificate2();
    Cert.Import(@"C:\users\foo\desktop\api\pubAndPrivateCert.pkcs12", "", X509KeyStorageFlags.PersistKeySet);

    ServicePointManager.ServerCertificateValidationCallback += ValidateServerCertificate;
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://api.foo.net/api/customer/v1/" + custId);
    req.ClientCertificates.Add(Cert);

    req.UserAgent = "LOL API Client";
    req.Accept = "application/json";
    req.Method = WebRequestMethods.Http.Get;

    string result = null;
    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
{
StreamReader reader = new StreamReader(resp.GetResponseStream());
result = reader.ReadToEnd();
}
return result;
}

每次我发出请求时,都会收到错误 400,当使用 Fiddler 查看响应时,我会收到以下信息

<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/0.6.32</center>
</body>
</html>

我认为它没有理由不发送证书,但解决 SSL 问题并不是很容易。我确实添加了一些调试语句来添加一些细节并停止使用 fiddler,他就是我得到的

这些错误来自 ValidateServerCertificate()

Certificate error: RemoteCertificateChainErrors
NotSignatureValid
The signature of the certificate cannot be verified.
1048576
Unknown error.

这些是引发的 WebException 的错误。

Cought Exception ProtocolError
The remote server returned an error: (400) Bad Request.
BadRequest
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/0.6.32</center>
</body>
</html>

这是 ValidateServerCertificate() 代码。它始终返回 true 以忽略任何证书错误。

    public static bool ValidateServerCertificate(object sender, X509Certificate certificate,X509Chain chain,SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
            return true;

        if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
        {
            Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
            foreach (var chainstat in chain.ChainStatus)
            {
                Console.WriteLine("{0}", chainstat.Status);
                Console.WriteLine("{0}", chainstat.StatusInformation);
            }
            return true;
        }

        Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

        // allow this client to communicate with unauthenticated servers. 
        return true;
    }

您的代码从本地文件加载客户端证书。如果将客户端证书导入到证书存储中(强烈建议这样做以保护私钥),您应该会取得更大的成功。那么你的代码应该看起来更像这样:

public string GetCustomer(int custId)
{
    // EDIT THIS TO MATCH YOUR CLIENT CERTIFICATE: the subject key identifier in hexadecimal.
    string subjectKeyIdentifier = "39b66c2a49b2059a15adf96e6b2a3cda9f4b0e3b";

    X509Store store = new X509Store("My", StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);

    X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindBySubjectKeyIdentifier, subjectKeyIdentifier, true);
    X509Certificate2 certificate = certificates[0];

    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://api.foo.net/api/customer/v1/" + custId);
    req.ClientCertificates.Add(certificate);

    req.UserAgent = "LOL API Client";
    req.Accept = "application/json";
    req.Method = WebRequestMethods.Http.Get;

    string result = null;
    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
    {
        StreamReader reader = new StreamReader(resp.GetResponseStream());
        result = reader.ReadToEnd();
    }
    return result;
}

See 导入证书以获得指示。该代码假定您已将带有公钥和私钥的证书导入到当前用户的个人证书文件夹(“我的”)中。

您不需要提供ServicePointManager.ServerCertificateValidationCallback。这允许您的应用程序改变server证书已验证。这不会影响服务器如何验证您的client证书。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebRequest 不发送客户端证书 的相关文章

随机推荐

  • 如何创建对角分割且两半可单击的布局?

    我需要创建一个布局 将屏幕对角线分成两个部分 并以不同的颜色作为背景 像这样的 我怎样才能实现这个目标 这可以按如下方式完成 创建一个FrameLayout 假设 50x50 像素 创建两个ImageViews 在FrameLayout并将
  • 从 Azure Active Directory 获取个人资料图片

    我们已将 Azure AD 设置为应用程序中的身份提供商 我们希望在应用程序中显示应来自 Azure AD 的个人资料图片 为了进行测试 我在 Azure AD 中添加了一个 Windows Live Id 帐户 具有个人资料图片 然后我们
  • 将模型中没有的字段添加到 Django REST 框架中的序列化器

    我有一个模型注释 创建时可能会也可能不会创建新用户 因此 我的 API 在创建新评论时需要密码字段 这是我的评论模型 class Comment models Model commenter models ManyToManyField C
  • 如何使用结构体属性设置默认值?

    我想知道如何将 DefaultValue 属性应用于结构属性 您可以注意到 Microsoft 使用表单的大小和许多其他属性来实现这一点 它们的值的类型是 Size Point 等 我想对我的自定义结构做同样的事情 DefaultValue
  • 如何在Python中获取匹配行之后的行

    我是一个业余爱好者 断断续续地使用 Python 一段时间了 抱歉 如果这是一个愚蠢的问题 但我想知道如果输入文件中的格式如下所示 是否有人知道一种简单的方法来获取一堆行 标题 1 Line 1 Line 2 Line 3 标题 2 Lin
  • 创建忽略鼠标和按键事件的 JavaFX 透明窗口

    我想制作一个 JavaFX 应用程序 基本上用一个覆盖整个用户屏幕Canvas对象 所以基本上我可以在用户屏幕上绘制任何内容 制作一个覆盖整个屏幕的窗口很简单 通过本教程可以使其基本上透明 https assylias wordpress
  • 用Java计算两个日期之间的天数

    我想要一个计算两个日期之间的天数的 Java 程序 输入第一个日期 德语表示法 带空格 dd mm yyyy 输入第二个日期 该程序应计算两个日期之间的天数 如何包含闰年和夏令时 My code import java util Calen
  • 响应式 UI 提示

    当我想创建响应式用户界面时 我只想要一些提示 我知道如何使用 Dispatcher Task BackgroundWorker Threads 我正在寻找更多高级提示 例如绑定提示 当我的 UI 上有 50 多个控件需要更新时 Priori
  • 缺少 python bz2 模块

    我已经安装在我的主目录中 spatel dev1 home spatel python 2 7 3 bin python V Python 2 7 3 我正在尝试运行一个需要 python 2 7 x 版本的脚本 但出现丢失 bz2 错误
  • 可以通过 Apache 下载文件吗?

    Path var lib foo txt 是否可以配置 Apache 以便有一些 HTTP URL 可以启动该文件的下载以及如何配置 Without htaccess file 那么那个 URL 会是什么 localhost var lib
  • Google 云存储 CNAME URL 重定向

    我在 Google Cloud 存储上有一个公共存储桶 wordgamesswf 可以通过网址访问对象http commondatastorage googleapis com wordgamesswf linguistics 我需要托管我
  • 原型还是内联,有什么区别?

    我刚刚学习 Javascript 我想知道是否使用原型声明 如下所示 function TSomeObj this name my object TSomeObj prototype showname function alert this
  • Pickle 类实例加上定义?

    我怀疑这是一个常见问题 但我还没有找到解决方案 我想要的非常简单 而且在技术上似乎是可行的 我有一个简单的 python 类 我想将它存储在光盘上 实例和定义在一个文件中 Pickle 将存储数据 但不存储类定义 有人可能会说类定义已经存储
  • 如何使 jenkins 在 Windows 批处理命令失败时失败?

    我在 jenkins 中使用一些 Windows 批处理命令 其中每个命令都可能失败 为了使 jenkins 作业在每一步都失败 这些批处理命令如下所示 net use m IP ADDRESS Whatever PASSWORD user
  • 在 Android 中直接将捕获的图像上传到 Cloudinary

    我想捕捉一张图片并直接上传到Cloudinary 我如何知道图片的名称以在上传声明中设置它cloudinary uploader upload nameofthepic Cloudinary emptyMap 这是我的代码 public c
  • 正则表达式捕获两个分隔符内单词的每次出现

    假设我有一长串文本 我想捕获每个单词this是在圆括号内提到的 我怎么能这么做呢 以下模式仅匹配第一个this 忽略之后出现的每一个事件 this g 例如 在以下文本上使用上面的模式 Etiam scelerisque nunc ac e
  • 使用 iText5 for .NET 读取 PDF 文件

    我使用 C 作为编程平台iTextSharp阅读 PDF 内容 我使用下面的代码来读取内容 但似乎是每页读取的 public string ReadPdfFile object Filename string strText string
  • 如何在其他类中使用PDO连接?

    我认为我在理解 OOP 的工作原理方面存在问题 我已经更改了它可以工作的代码 但这不是我认为的正确方式 以下场景 不 我不是自己创建用户登录 它实际上只是为了本地开发人员更好地理解 OOP 我有一个database php 文件 class
  • iOS Safari 隐私浏览 localStorage 和 sessionStorage 支持吗?

    我在 StackOverflow 上发现了一些问题 解决了 iOS Safari Private Browsing 的特定功能和sessionStorage and localStorage 但我还没有找到明确的资源来表示 iOS Safa
  • WebRequest 不发送客户端证书

    我正在为 REST API 编写一个客户端 为了对 API 进行身份验证 我必须使用提供给我的证书 这段代码如下 public string GetCustomer int custId X509Certificate2 Cert new