How to set certificate in C# Win Application - c#

Im using a webservice in my program.
this is the web service : "https://X.Y.Z.W/ib/ws/openbill.asmx?wsdl"
It works as local. when I write this on Internet Explorer, I can see the proper page after selecting "Continue to this website (not recommended)" in this attachment :
but when I want to access to this, in my c# code, I get this exception :
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
So how can I access this in my c# program?

I think you should first acquire a certificate file, and then use it in your code. For example, to set it for a SMTPClient object:
string certificate = "Certificate.cer";
X509Certificate cert = new X509Certificate2(certificate);
MailMessage message = new MailMessage(from, to);
SmtpClient client = new SmtpClient(server);
client.ClientCertificates.Add(cert);
client.Send(message);

The web service that you are trying to connect to is using SSL/TLS. When you open the web service via internet explorer, it is giving you a warning that it cannot validate the certificate of the web service.
This has many reasons, and I guess in your case it is that the certificate that the web service is using is not for X.Y.Z.W.
Another reason could be that your machine does not trust the root issuer of the web service certificate. But from the error message that you have, I don't think this is the case.
You can view the certificate in IE by click on "Continue on this web site..", and the clicking on "Certificate Error", and the "View certificates".
From there, you will view the certificate. Go to details, and look for DNS Name inside Subject Alternative Name.
The DNS name is the name of the machine that the web service certificate was given for.
I guess in your case it will not be X.Y.Z.W.
Is the web service yours? can you obtain a different certificate for it? If so, can make sure you create a certificate that has the correct DNS name.
As a last resort, you can skip certificate validation from your code (this is not recommended). Take a look at this question.

Related

Could not stablish secure channel for SSL/TLS adding new service reference in Visual Studio

This is the situation: New project (console or forms). I go to References, add new service reference. I write the url and I get an error about that the request is cancelled due to that it can't be stablished a secure channel for SSL/TLS. Without https, it works.
A friend tested in other windows 10 and no problem.
With Iexplorer or chrome, no problem, I see the xml of the wdsl, but with visual studio impossible, it doesn't work. I've tested all the posts that I've seen but nothing. The only way is to generate the proxy class with wdsl.exe
Any idea about this?
Regards.
Do you mean that you fail to invoke the wcf service by adding the service reference when the service is hosted over https?
If the server uses the self-signed certificate as the server identity credential, there is a default step validates the server certificate on the client side. you could refer to the following code.
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
try
{
var result = client.SayHello();
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Feel free to let me know if the problem still exists.
This is because the SSL certificate is not installed in your certificate repository.
Open the web service URL in browser.
It would prompt you to install the SSL CA to your local machine's certificate repository.
The dialog would be showing two options "Local User", "Local Machine".
You MUST select "Local Machine".
Then you should be able to add service reference even using SSL url.
This should solve your issues.

Webpage sometimes cannot connect to other url with SSL

We have an application (WebAPI, let's name it "X") working on IIS on Windows Server 2012 R2. Sometimes "X" cannot connect to other independent API's on the web. We got error:
The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel.
The remote certificate is invalid according to the validation
procedure.
I've done some testing and at the same time "X" cannot download https://google.com (using WebClient class) but I can browse it with web browser on that current server.
Also I tried to ignore server certificate errors for whole application (code below) but it didn't help too.
protected void Application_Start()
{
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
}
My clients have no problem connecting to "X". Also when the error occures on one server I am able to successfully connect (https://google.com for example) on other servers with different instance of "X".
What could be wrong?
It sounds like your IIS web application is running under a user context that doesn't have access to the certificates on the machine. However, the browser is running under a different user context that does have access. That explains your test results.
If the user does have access to the certificates, then possibly you will need to download the certificates from the independent API's. See this: http://brainof-dave.blogspot.com.au/2008/08/remote-certificate-is-invalid-according.html
Check out these resources too:
https://blogs.msdn.microsoft.com/saurabh_singh/2009/07/02/required-permissions-when-calling-a-web-service-using-client-certificate-for-authentication-in-an-asp-net-web-application/
https://technet.microsoft.com/en-us/library/cc772237(v=ws.10).aspx

Implementing Swedish Swish payment - C# - Could not create SSL/TLS secure channel - Certificate signing request

As described in this question I'am able to connect with Swish using their test account and test certificate.
C# HttpClient with X509Certificate2 - WebException: The request was aborted: Could not create SSL/TLS secure channel
However when using my own generated certificate I still get the generic error Could not create SSL/TLS secure channel using C# HttpClient.
I have been following these guides for Swish certificate administration:
https://www.getswish.se/content/uploads/2015/11/Guide-Certifikatsadministration_20151210.pdf
https://www.getswish.se/content/uploads/2015/06/Guide-Swish-API-170324-utan-%C3%A4ndringsmarkering.pdf
Since we are using IIS I created the certificate signing request using this: IIS -> Server Certificates -> Create Certificate Request…. I choose Microsoft RSA Schannel Cryptographic Provider with a bit length of 2048 since the documentation says it should be PKCS#10 with 2048-bit RSA key. My theory is that I'm doing something wrong here. Since we are developing this now and the application is not running on a domain name yet I set Common Name to localhost. Could this be the problem and If so what value should I put there for it to work from our environments? The test certificate works without a problem as I mentioned before.
After this I pasted the value from the file created at the service https://getswishcert.bankgirot.se/ and got a PKCS#7-file back (.p7b, also tried with .pem).
I then wen't to IIS -> Server Certificates -> Complete Certificate Request… to import the file.
When imported the Certification Path and everything else looks good as far as I can tell.
I also tried exporting the certificate to .pfx via MMC -> Select certificate -> right click -> All Tasks -> Export. Choose to export it with private key and password protected. Then imported it under Certificates - Current User. I can then choose the certificate in Chrome but I get the error `ERR_SSL_PROTOCOL_ERROR. The test certificate works in Chrome as well.
Turned out the certificate was OK. The problem was that the application was trying to connect to https://mss.swicpc.bankgirot.se/ (test environment) with the live certificate instead of https://swicpc.bankgirot.se/ (live).
Found with logging from here.

Getting "The remote certificate is invalid according to the validation procedure" when SMTP server has a valid certificate

This seems a common error but while I've found a work-around (see below) I can't pin down the reason I'm getting it in the first place.
I am writing SMTP functionality into our application and I'm attempting to add SSL functionality to the working SMTP we already have.
I am testing using our company's MS Exchange server and specifically the webmail option enabled on that. I can send emails internally through my code by not authenticating my connection and sending anonymously, however those emails won't relay to external email addresses due to our companies policy. Besides which I am programming this for our customers and they don't all allow open relay and/or anonymous connections.
I believe the Exchange server is using Explicit SSL/ TLS. I have tried telnet to the server's address on port 25 and got a text response, human readable response, which according to some of my searches previously means it's using Explicit SSL/ TLS.
I have the following test code
SmtpClient SMTPClient = new SmtpClient(webmailaddress);
SMTPClient.Port = 25;
SMTPClient.UseDefaultCredentials = true;
SMTPClient.EnableSsl = true;
System.Net.Mail.MailMessage Message = new `
System.Net.Mail.MailMessage(emailFrom,emailTo,subject,body);
SMTPClient.Send(Message);
During my searching for a solution I came across this "The remote certificate is invalid according to the validation procedure." using Gmail SMTP server
From which I got the following code...
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
public static bool ValidateServerCertificate(object sender,X509Certificate certificate,X509Chain chain,SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
else
{
if (System.Windows.Forms.MessageBox.Show("The server certificate is not valid.\nAccept?", "Certificate Validation", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
return true;
else
return false;
}
}
This works in my test code. HOWEVER the actual process I'm writing (rather than my test code) is going to run in the background and can't really ask the user (instead it reports errors in the windows error log).
As I started, my question is really why I'm getting this error at all. If I go to https:webmail.ourdomain.co.uk in a browser it shows a valid certificate and there is no option to install the certificate (as I would have done if it were a self-signed one).
However when I run my code, with a debug break poing in the ValidateServerCertificate method, I look at the certificate values and see an issuer of our local server and 'don't use before', and 'don't use after' properties of today. This does not match the certificate I am getting.
I've also checked what the sslPolicyErrors flags are in the debug of ValidateServerCertificate, and they are showing "RemoteCertificateChainErrors" and "RemoteCertificateNameMismatch".
So what am I missing about this... why is it not using the correct certificate? If there are steps I need to take to install the certificate locally for it to use then I need to know them so I can tell my customers what to do if they get this.
I don't want to just by-pass the check by returning true from the ValidateServerCertificate method, and because it's a background process I can't ask the user, so I need to understand how to get my code to use the correct/trusted certificate.
Hope someone can advise.
The answer I have finally found is that the SMTP service on the server is not using the same certificate as https.
The diagnostic steps I had read here make the assumption they use the same certificate and every time I've tried this in the past they have done and the diagnostic steps are exactly what I've done to solve the problem several times.
In this case those steps didn't work because the certificates in use were different, and the possibility of this is something I had never come across.
The solution is either to export the actual certificate from the server and then install it as a trusted certificate on my machine, or to get a different valid/trusted certificate for the SMTP service on the server. That is currently with our IT department who administer the servers to decide which they want to do.
Old post but as you said "why is it not using the correct certificate" I would like to offer an way to find out which SSL certificate is used for SMTP (see here) which required openssl:
openssl s_client -connect exchange01.int.contoso.com:25 -starttls smtp
This will outline the used SSL certificate for the SMTP service. Based on what you see here you can replace the wrong certificate (like you already did) with a correct one (or trust the certificate manually).
Old post, but I thought I would share my solution because there aren't many solutions out there for this issue.
If you're running an old Windows Server 2003 machine, you likely need to install a hotfix (KB938397).
This problem occurs because the Cryptography API 2 (CAPI2) in Windows
Server 2003 does not support the SHA2 family of hashing algorithms.
CAPI2 is the part of the Cryptography API that handles certificates.
https://support.microsoft.com/en-us/kb/938397
For whatever reason, Microsoft wants to email you this hotfix instead of allowing you to download directly. Here's a direct link to the hotfix from the email:
http://hotfixv4.microsoft.com/Windows Server 2003/sp3/Fix200653/3790/free/315159_ENU_x64_zip.exe

Calling HTTPS JBoss service from C# code throws an authentication error

I'm trying to call a JBoss service from a C# program and I'm getting an annoyingly vague error.
JbossService proxy = new JbossService();
proxy.Credentials = new NetworkCredential("ME", "thepwd");
proxy.Url = //https url snipped
proxy.CookieContainer = new CookieContainer();
proxy.PreAuthenticate = true;
Console.WriteLine("Calling service...");
queryResponse qr = proxy.query();
Console.WriteLine("Done.");
The exception and inner exception thrown are as follows:
exception : The underlying connection was closed: An unexpected error occurred on a send.
inner exception : Authentication failed because the remote party has closed the transport stream.
I'm not quite sure what this means, other than perhaps that JBoss likes me even less than I like it. I'm calling from the local machine so I don't think it's a networking issue. Has anyone seen this before?
This usually happens when your client cannot verify trust over https with the server (usually because the server certificate is self signed or if it is signed by a root authority not installed on your client machine.
Easy fix (although there are security consequences)....somewhere in your initialization code add the following:
System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true;};
Basically this replaces the application wide handling of server certificate validation and causes your application to accept any certificate. If you want to get finer grained, you can examine the certificate and put some logic in the method.
This works for anything based on System.Net, so it should work for Web Services and any thing based on WebRequest.
I haven't used JBOSS. This is how I troubleshoot similar problems, when using Microsoft technologies -- the same issues may be affecting your program:
Firewall settings or network issue (try connecting manually, to rule this out)
Self-service certificate issues:
Check the following certificate values:
Ensure the server's certificate issuer has a valid, matching issuing trusted root Certificate Authority (CA), on the same machine
The server certificate subject name matches the machine name exactly
The machine name the client is accessing matches that defined in the server certificate
An administrator account set (server) certificate thumbprint
Try recreating the SSL Certificate on both servers)
Try creating your own CA cert, add to trusted publishers, and then create an SSL sert based on that

Categories