使用 HttpWebRequest 的 .Net 客户端身份验证设置
.Net client authentication setup using HttpWebRequest
这更多是关于如何让 HttpWebRequest 工作,或者即使 HttpWebRequest 是正确的实现。在过去的几年里,我的 C# 和 .Net 技能已经失效,所以我希望我能得到原谅。
我正在尝试访问需要客户端身份验证的安全 Web 服务。我有四个证书可以用来解决这个问题。
• 根证书
• 中间根证书
• 设备证书
• 私钥
服务器是 Java,这些证书位于 .jks 格式的 trustore 和 keystore 中。我将它们拉入 .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 done 之后。
好吧,我觉得我在原来的时候已经很接近了,但我是这样解决的:
request.ClientCertificates = new X509Certificate2Collection(
new X509Certificate2(
truststore,
password));
"trustore" 文件是一个 .p12 文件,其中包含上面列出的证书。 .p12 信任库可以通过 keytool 和 openssl 从 .jks 信任库创建。那里有很多关于如何做到这一点的信息。
这更多是关于如何让 HttpWebRequest 工作,或者即使 HttpWebRequest 是正确的实现。在过去的几年里,我的 C# 和 .Net 技能已经失效,所以我希望我能得到原谅。
我正在尝试访问需要客户端身份验证的安全 Web 服务。我有四个证书可以用来解决这个问题。
• 根证书 • 中间根证书 • 设备证书 • 私钥
服务器是 Java,这些证书位于 .jks 格式的 trustore 和 keystore 中。我将它们拉入 .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 done 之后。
好吧,我觉得我在原来的时候已经很接近了,但我是这样解决的:
request.ClientCertificates = new X509Certificate2Collection(
new X509Certificate2(
truststore,
password));
"trustore" 文件是一个 .p12 文件,其中包含上面列出的证书。 .p12 信任库可以通过 keytool 和 openssl 从 .jks 信任库创建。那里有很多关于如何做到这一点的信息。