ssl - 具有相互身份验证的 WebRequest
问题描述
来自 Crypt32 的评论后的额外信息(谢谢 Crypt32!)
我必须将数据发送到服务器。我需要相互认证:服务器需要确定是我,我需要确定服务器确实是我信任的服务器。这需要在 Windows 程序中使用。
为了识别自己,服务器将向我发送一个由我信任的证书颁发机构颁发的证书:根证书和中间证书:
- 根 CA-G2.PEM
- 中级 CA-G2.PEM
为了识别我,该组织给了我一个证书和一个私钥
- 根 CA-G3.PEM
- 中级 CA-G3.PEM
- MyCertificate.CRT (= pem) 和 MyCertificate.Private.Key (=RSA)
我已将所有根证书和中间证书导入 Windows 密钥库。
要发送消息:
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
解决方案
错误的 IsMutuallyAuthenticated 是否表明我的身份验证有问题?
是的,它确实。因为您只添加了客户端证书的公共部分。没有指定关联的私钥。要么使用证书存储中的证书(假设证书存储包含私钥),要么从 PFX 导入证书。
更新:
现在您的客户端身份验证代码看起来正确。下一步是检查您的客户端证书是否受服务器信任。
推荐阅读
- postgresql - Postgresql 查询运行缓慢和快速。解释计划显示高共享读取
- pandas - 如何使用 spark 将数组转换为 Dataframe?
- python - 如何检查数字是否可以被另一个Python整除
- php - Wordpress 中的自定义 php+ajax 表单不起作用
- python - 我怎样才能格式化我的回调,以便破折号图正常工作?
- php - 如何显示可以出现在红色圆圈中的最近标记?
- excel - 模拟IE EXCEL中的双击事件,VBA交互
- android - 从另一个选项卡导航时,viewpager 内的 Recyclerview 会自行重复项目
- wordpress - 如何使用最终的“AND”过滤一组或“OR”结果,该结果与“OR”中的“NOT EXIST”安全工作
- c - 将 char 指针数组的值复制到结构中