Accessing ssl server (web service) from .net client - c#

I’m tryng to access a ssl server (web service) from a .net client (c#). I have access to a java client code that can connect to the server. Included in the source code are 3 files (saPubKey.jks, WebServices.pfx and trustStore) and I think that only 2 of the 3 are used in the java example.
private void setSSLConnection(WSBindingProvider bp){
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(this.getClass().getClassLoader().getResourceAsStream("WebServices.pfx"), "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyStore ts = KeyStore.getInstance("JKS");
ts.load(this.getClass().getClassLoader().getResourceAsStream("trustStore"), "pass".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
bp.getRequestContext().put(JAXWSProperties.SSL_SOCKET_FACTORY, sslContext.getSocketFactory());
}
The code I have for the c# client is this
var clientCertificate = new X509Certificate2(#"C:\WebServices.pfx", "password");
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://blablabla.org:700/fws/ftrs");
req.ClientCertificates.Add(clientCertificate);
req.Headers.Add("SOAPAction", "\"https://blablabla.org:700/fws/ftrs/Rgdvice\"");
req.ContentType = "text/xml;charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";
using (Stream stm = req.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
stmw.Write(soap);
}
}
WebResponse response = req.GetResponse(); //(500) Internal Server Error.
Stream responseStream = response.GetResponseStream();
Method req.GetResponse() throws "(500) Internal Server Error."
With no client certificates added I get: "An unexpected error occurred on a send."
I also tried this line of code with no luck:
ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
I'm new to ssl and certificates, and really need help accessing the ssl server from c#.

This could be unrelated but make sure web service is not in the app_code folder.

Related

Connecting to RESTful site using Script Task

I have been trying various combinations of HttpWebRequest objects (in SSIS) to connect to webservices geocoding site to pull back individual geocoding information with no luck. This is a JSON response and https URL.
string wUrl = "https://geocoding.geo.census.gov/geocoder/geographies/onelineaddress?address=1600+Pennsylvania+Ave+NW,+Washington,+DC,+20500&benchmark=Public_AR_Current&vintage=4&format=json";
X509Certificate cert = X509Certificate.CreateFromCertFile("C:\\Users\\kwhauser\\geocode.cer");
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(wUrl);
//WebRequest httpWReq = WebRequest.Create(wUrl);
//httpWReq.Method = "GET";
httpWReq.ClientCertificates.Add(cert);
//httpWReq.ContentType = "application/json";
//ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
//ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
//HttpWebResponse httpWResp = (HttpWebResponse)httpWReq.GetResponse();
//HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
try
{
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
//WebResponse response = httpWReq.GetResponse();
//Stream responseStream = response.GetResponseStream();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
if (ex.InnerException != null)
MessageBox.Show(" InnerException: " + ex.InnerException.Message);
}
It doesn't matter if I try to load cert from file or use the callback one, I still get the same error message:
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
DotNet framework version is 4.7. The site expects TLS12. I've added simple REST Client extension to chrome and tested the URL with success. It fails on the GetResponse.
What am I missing?
System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;

Adding .pfx certificate to HttpWebRequest fails from Web application

I have created a Asp.net web application-C#, where I need to send a HttpWebRequest with a .pfx certificate.
I have installed the certificate to the personal certificates folder(added rights for user NETWORK SERVICE) and able to see it in the X509Certificate2Collection and no issues while adding the certificate to the HttpWebRequest.
But it throws cannot connect to server error while fetching the response (HttpWebResponse)req.GetResponse()
I am facing this issue only from web application, the same code works fine(got the correct response) when i tried using a C# console application.
X509Store oLocalMachineStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
X509Certificate2Collection oCertColl;
X509Certificate oCert = new X509Certificate();
oLocalMachineStore.Open(System.Security.Cryptography.X509Certificates.OpenFlags.ReadOnly);
oCertColl = oLocalMachineStore.Certificates.Find(System.Security.Cryptography.X509Certificates.X509FindType.FindByIssuerName, "mycertificate issuer", false);
oLocalMachineStore.Close();
foreach (X509Certificate oCertFromStore in oCertColl)
{
if (oCertFromStore.Issuer.Contains("mycertificate issuer"))
{
oCert = oCertFromStore;
oCert.Import(#"certlocation\mycertificate.pfx", "pwd", X509KeyStorageFlags.MachineKeySet);
break;
}
}
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("destination URL");
req.ClientCertificates.Add(oCert);
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();
}
The issue got resolved after adding proxy to the http request.
req.Proxy = New Net.WebProxy("ProxyURL", False);
But still i have no idea, how it worked when i tried with the same code from a console application with out adding proxy.
If anyone has any idea on this please share.

Invoking a SOAP web service: the request was aborted: Could not create SSL/TLS secure channel

I'm trying to invoke a SOAP web service from a .NET application. The web services uses HTTPS (I got that from the URL inside the WSDL) but I can't figure out whether I should invoke it with TLS or SSL. Here's my code:
try
{
string soap = "<BigXmlSOAPHeader></BigXmlSOAPHeader>"
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ws_uri);
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) =>
{
return true;
};
byte[] bytes;
bytes = System.Text.Encoding.ASCII.GetBytes(soap);
request.ContentType = "text/xml; encoding='utf-8'";
request.Timeout = 1000000000;
request.ContentLength = bytes.Length;
request.Method = "POST";
Stream requestStream = request.GetRequestStream(); // it fails here
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
HttpWebResponse response;
response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
XmlTextReader reader = new XmlTextReader(responseStream);
}
catch (Exception ex)
{
DoSomethingWithException(ex);
}
The Exception message is The request was aborted: Could not create SSL/TLS secure channel.
When I copied my header (from debugging) and used it in SoapUI to invoke the web service, it worked which means there's no problem with the web service itself.
UPDATE:
I restarted my application pool in IIS when this occured and it solved the problem. I can't find a logical explanation to this...
Please help.

How to invoke a Web Service which requires a certificate in C#?

I need to communicate with a third party which has a .asmx web service. This web service is using https. I have the required certificate (.pfx).
When first trying to add this service using Add Service Reference in Visual Studio, I got an error. I got passed this error by importing the certificate into the Personal store. After I did that, I tried to add the Service Reference again and it works. So now I can create an instance of the web service. Nice.
But now I want to invoke the service. And when I do that I get this error:
302 Notification: Digital Certificate Missing
So how can I tell my service to use the right certificate?
I finally managed to fix my problem as follows:
var service = new Service1SoapClient();
service.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.TrustedPublisher, X509FindType.FindByIssuerName, "name_of_issuer");
((BasicHttpBinding)service.Endpoint.Binding).Security.Mode = BasicHttpSecurityMode.Transport;
((BasicHttpBinding)service.Endpoint.Binding).Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
Please use Certificate.pfx and install it with password.
Try adding this before getting the request stream:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
request.ProtocolVersion = HttpVersion.Version10;
request.ClientCertificates.Add(new X509Certificate2("YourPfxFile(full path).pfx", "password for your pfx file");
Depending on your security requirements and environment, you may need to use a different SecurityProrocolType value.
I was also facing "The request was aborted: Could not create SSL/TLS secure channel" while requesting a web service.
Fixed issue with below code, hope this will help someone and save time.
HttpWebRequest web_request = (HttpWebRequest)WebRequest.Create("https://yourservices/test.asmx");
web_request.ContentType = "text/xml;charset=\"utf-8\"";
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
web_request.ProtocolVersion = HttpVersion.Version10;
X509Certificate2Collection certificates = new X509Certificate2Collection();
certificates.Import(certName, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
web_request.ClientCertificates = certificates;
web_request.Accept = "text/xml";
web_request.Method = "POST";
using (Stream stm = web_request.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
stmw.Write(soap);
}
}
WebResponse web_response = null;
StreamReader reader = null;
try
{
web_response = web_request.GetResponse();
Stream responseStream = web_response.GetResponseStream();
XmlDocument xml = new XmlDocument();
reader = new StreamReader(responseStream);
xml.LoadXml(reader.ReadToEnd());
}
catch (Exception webExp) {
string exMessage = webExp.Message;
}

SSL HttpWebRequest Issues

I am attempting to access an api which they had me install a local cert via mmc I have done so on my local windows 7 machine so I could test out the service. I'm using a simple winforms app to test. I'm assuming this is a self signed cert server side so I'm hoping to bypass the exception for dev purposes.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(postData);
req.Method = "POST";
req.ContentType = "application/x-www-form-uriencoded";
req.KeepAlive = true;
req.AllowAutoRedirect = false;
X509Store store = new X509Store(StoreName.Root,StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate cert = new X509Certificate();
for (int i = 0; i < store.Certificates.Count; i++)
{
if (store.Certificates[i].SerialNumber == "XXXX")
{
cert = store.Certificates[i];
}
}
req.ClientCertificates.Add(cert);
req.PreAuthenticate = true;
try
{
using (WebResponse resp = req.GetResponse())
{
Stream responseStream = resp.GetResponseStream();
using (StreamReader responseStreamReader = new
StreamReader(responseStream, new ASCIIEncoding()))
{
respString = responseStreamReader.ReadToEnd();
}
}
}
catch (Exception ex)
{
// there is a problem
}
I'm getting the following exception in the try catch:
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
I do have a certificate object in the variable "cert"
When I go to the api url in my browser I get the caution warning but then can proceed and get data.
I have tried the other fixes recommended on stackoverflow such as suppressing the exception.
ServicePointManager.ServerCertificateValidationCallback = new
RemoteCertificateValidationCallback
(
delegate { return true; }
);
I realize there are quite a few of these questions similar to this and trust me I have read through them all. Thanks for any suggestions they are appreciated.
Hey the following finally fixed it for me. I went to the api server address in my browser and exported their certificate to a file on my desktop. I then opened mmc and installed the certificate like in the following link:
http://support.esri.com/en/knowledgebase/techarticles/detail/38408
After I installed I had no issues calling the webservice and the exception went away.

Categories

Resources