I'm making an httpwebrequest using a public Root authority Certificat file X509. I only have the public key, not the private key. Everything works fine from a Console app but it does not work from an asp.net app. I get the error: "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
The option to disable Validation is not an option.
Here is the code
HttpWebRequest req = (HttpW开发者_如何学CebRequest)WebRequest.Create("https://xxxxxxx/gateway.aspx");
string post = "abcdef";
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
req.ContentLength = post.Length;
var cert = System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile(@"c:\temp\root.cer");
req.ClientCertificates.Add(cert);
StreamWriter stOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
stOut.Write(post.ToString());
stOut.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Here is the System Logs from System.Net and System.Net Sockets.
System.Net Information: 0 : [5928] SecureChannel#8106798 - A certificate chain could not be built to a trusted root authority.
System.Net Information: 0 : [5928] SecureChannel#8106798 - Remote certificate was verified as invalid by the user.
System.Net.Sockets Verbose: 0 : [5928] Socket#7486778::Dispose()
System.Net Error: 0 : [5928] Exception in the HttpWebRequest#51319244:: - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
System.Net Error: 0 : [5928] Exception in the HttpWebRequest#51319244::EndGetRequestStream - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Further info
If I use this code (from CodeGuru)
public static bool ValidateServerCertificate(object sender,
X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors ==
SslPolicyErrors.RemoteCertificateChainErrors) {
return false;
} else if (sslPolicyErrors ==
SslPolicyErrors.RemoteCertificateNameMismatch) {
System.Security.Policy.Zone z =
System.Security.Policy.Zone.CreateFromUrl
(((HttpWebRequest)sender).RequestUri.ToString());
if (z.SecurityZone ==
System.Security.SecurityZone.Intranet ||
z.SecurityZone ==
System.Security.SecurityZone.MyComputer) {
return true;
}
return false;
}
return true;
}
I ultimately get the error:
Remote Certificate Chain Error
This problem can be fixed with this added to Application_Start:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
It basically allows for a mismatch between the server and its certificate.
Source:
http://www.ben-morris.com/asp-net-web-services-and-ssl-certificates-establishing-a-trust-relationship
Note: This workaround is not recommended for production
It sounds like the issue could be what is posted on this link. The ASPNET worker process requires the cert name to match the server name. There are work arounds that can be implemented with test environments.
For certificate generation you can use a free program called SelfSSL.exe with commands such as:
SelfSSL.exe /T /N:CN=localhost /V:999 /Q
(where "localhost" is cert name)
And:
winHTTPCertCfg.exe -g -c local_machine\my -s localhost -a Administrators
(to grant admins access to the cert)
精彩评论