ssl - 具有相互身份验证的 WebRequest

标签 ssl x509certificate

在 Crypt32 发表评论后在最后提供额外信息(谢谢 Crypt32!)

我必须向服务器发送数据。我需要相互认证:服务器需要确定是我,我需要确定服务器确实是我信任的服务器。这需要在 Windows 程序中进行。

为了识别自己,服务器将向我发送由我信任的证书颁发机构颁发的证书:根证书和中间证书:

  • 根 CA-G2.PEM
  • 中级 CA-G2.PEM

为了识别我,组织给了我证书和私钥

  • 根 CA-G3.PEM
  • 中级 CA-G3.PEM
  • MyCertificate.CRT (= pem) 和 MyCertificate.Private.Key (=RSA)

我已将所有根证书和中间证书导入到 Windows keystore 中。

发送消息:

const string url = "https://...//Deliver";
HttpWebRequest webRequest = WebRequest.CreateHttp(url);

// Security:
webRequest.AuthenticationLevel=AuthenticationLevel.MutualAuthRequired;
webRequest.Credentials = CredentialCache.DefaultCredentials;

// Should I add my certificate?
X509Certificate myCertificate = new X509Certificate("MyCertificate.CRT");

// Should I add Certificate authorities?
// only the CA-G2 authorities, so my WebRequest can trust the certificate
// that will be sent by the Server?
// or Should I also add the CA-G3 who issued MyCertificate

// and what about MyCertificate.Private.Key, the RSA file?

// Fill the rest of the WebRequest:
webRequest.Method = "Post";
webRequest.Accept = "text/xml";
webRequest.Headers.Add("SOAP:Action");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
... etc

// do the call and display the result
using (WebResponse response = webRequest.GetResponse())
{
    using (var reader = new StreamReader(response.GetResponseStream()))
    {
        string soapResult = reader.ReadToEnd();
        Console.WriteLine(soapResult);
    }
}

WebResponse 没有指示任何错误。返回的数据是空(非空)字符串。然而:

response.StatusCode == NoContent (204)
soapResult == String.Empty
response.IsMutuallyAuthenticated == false

NoContent 和空数据结果是预期的。错误的 IsMutuallyAuthenticated 是否表示我的身份验证有问题?

添加信息

Crypt32 建议我将 MyCertificate.CRT 和 MyCertificate.Private.Key 转换为一个 PFX(或 P12)文件。

为此,我使用 openssl。

我将 CA-G3 文件串联成一个 TrustG3.Pem 并创建了 P12 文件:

openssl.exe pkcs12 -export -name "<some friendly name>"
                   -certfile TrustG3.Pem
                   -in MyCertificate.CRT
                   -inkey MyCertificate.Private.Key
                   -out MyCertificate.P12

在提供密码后,创建了一个正确的 Pkcs12 文件 (PFX)。源代码略有变化:

HttpWebRequest webRequest = WebRequest.CreateHttp(url);

// Security:
webRequest.AuthenticationLevel=AuthenticationLevel.MutualAuthRequired;
webRequest.Credentials = CredentialCache.DefaultCredentials;
var p12Certificate = new X509Certificate("MyCertificate.P12", "my password");
webRequest.ClientCertificates.Add(p12Certificate);

唉,这并没有帮助。 webResponse 仍然说:

response.IsMutuallyAuthenticated == false

最佳答案

Does the false IsMutuallyAuthenticated indicate that something is wrong with my authentication?

是的,确实如此。因为您只添加客户端证书的公共(public)部分。没有指定关联的私钥。使用来自证书存储的证书(假设证书存储包含私钥)或从 PFX 导入证书。

更新:

现在您的客户端验证码看起来是正确的。下一步是检查您的客户端证书是否受服务器信任。

关于ssl - 具有相互身份验证的 WebRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55609894/

相关文章:

python - Python 中真正的非阻塞 HTTPS 服务器

javascript - 如何在外部安全网站上创建超时

wcf - 使用 TransportWithMessageCredential 时,受信任的人商店是否需要客户端证书

java - 在 Java KeyStore 中导入私钥/公钥对

security - 据称,在 .NET 4.5 中实现 IDisposable 的 X509Store 在哪里?

c# - 使用 C# 从我的 Java 证书中获取公钥

php - magento 下的 sslv3 警报握手失败

php - 配置问题 : multi-domain auto SSL from LetsCncrypt using OpenResty & lua-resty-auto-ssl

azure - 使用 RDM 使用 SSL 通过 Ngnix 安全连接到 Redis 容器

php - 在 PHP 中签署公共(public) x509 证书