Link to home
Start Free TrialLog in
Avatar of Baub Eis
Baub EisFlag for United States of America

asked on

The request was aborted: Could not create SSL/TLS secure channel

Guessing by the number of previous questions this has been asked a lot, but I still haven't found my issue.  I have a website on a IIS server using asp .net for the language.  I'm calling an API to another site for data and getting this error.   I've researched quite a bit.  The script uses TLS1.1 for the version it needs.  I've scanned server to make sure it supports the protocol and it does.  I think maybe its some sort of rights issue with the webscript using a different user or something thats not granted rights to the ssl certificate?  Or that its trying to use the wrong protocol?  How I determine which user it authenticating to for running the aspx.net script and where would they be set?  Any other ideas would be great to persue.


{
  "ClassName": "System.Net.WebException",
  "Message": "The request was aborted: Could not create SSL/TLS secure channel.",
  "Data": null,
  "InnerException": null,
  "HelpURL": null,
  "StackTraceString": "   at System.Net.HttpWebRequest.GetResponse()\r\n   at DMXzone.ServerConnect.Module.ApiModule.Send(JObject options) in C:\\Development\\Server Connect\\ASPNET_Source\\DMXzone API\\Module\\ApiModule.cs:line 126",
  "RemoteStackTraceString": null,
  "RemoteStackIndex": 0,
  "ExceptionMethod": "8\nGetResponse\nSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\nSystem.Net.HttpWebRequest\nSystem.Net.WebResponse GetResponse()",
  "HResult": -2146233079,
  "Source": "System",
  "WatsonBuckets": null
}

Open in new window

Avatar of Charlie Arehart
Charlie Arehart

I'd take a different tack than your questions. I don't KNOW that this will lead to your solution, but it may.

You say you're calling using tls 1.1, but that you have "scanned server to make sure it supports the protocol and it does" .

Note first that that scan would likely be reporting whatever (for that server) serves as the public entry point to the server. That may be a web server there (like iis), or it may even be some other intermediate gateway (like cloudflare or a load balancer) that might then pass the request on to the actual app that is processing the api call.

But I will note that if that "actual app that processes the api call" may be a Java-based app server (regardless of your .Net client), then starting with updates in Apr 2021, Java (8, 11, 17 and above) now by default rejects communication via tls 1.1 or earlier. I know 100% for sure that affects calls OUT of Java, but I can see how it would affect also a call IN to Java. I'd not ever tested the latter (and I'm on a phone as I write), but this seems worth your considering as a possible explanation.

Some good news is that that is configurable, via a line in a java.security properties file on the server (whose location changes depending on whether on Java 8, or 11 or above). I have a blog post with the details. 

But you may have no control over that server you're calling, of course.

So instead I'd wonder: have you tried yet to call via tls 1.2 or above? I know you felt it was not "needed", but if it works, this may have been the issue.

Let us know how it goes or what you think. 
Avatar of Baub Eis

ASKER

So you are saying that the API call recipient could be using JAVA on their side? Therefore it won't work with TLS 1.1, it has to be 1.2?  
I do have server access through RDP to the IIS server
Let me try to setup another api to a different source and see if it does the same thing?  Would be a good test.
Well, I'm saying it's possible. And changing your client code to call using tls 1.2 would be the simplest way to find out.

Then if it's so, either call it a day (leaving it at that) OR a different option would be for the api server owner to modify their Java to continue to support tls1.1.

Really, I think you should rule out the first, since that's in you caller/client.
Gotcha let me see if I can dial up a quick open source api of some sort to test against.
Well, are you saying that for some reason you can't just change your current .Net client code calling the current api, to call via tls 1.2? You'd said you were calling via 1.1, so I didn't elaborate further, thinking it would perhaps be trivial for you to change, for a test. 
Ok, so I was able to connect to a different API no problem with a https call.  So I'm guessing I need to look at some other issues then.  This was very helpful in pointing me in the right direction. awesome.

thanks
Baub


Please consider and respond to my last comment. I know our messages were crossing back and forth within minutes. but I'm not seeing how your test confirmed "other issues". I realize you see how it does, but I mean more specifically I don't see how your test either affirmed or denied what I was proposing.

And you may not need to deal with any "other issues", if it's what I proposed, and if my solution  (changing your client to call via TLS 1.2) works. Just trying to save you more than that small amount of effort, if possible. :-)
I'm guessing that the API provider was requiring TLS 1.2?  my software provider has said it uses TLS 1.1. so I have emailed them to see if it's possible to update the connecter(.net software code) to 1.2. and I've also emailed the API provider to see if they can support TLS 1.1 or not. I am waiting for replies from both.

by being connected to another api confirmed that my server settings are functioning correctly and that it might just be an issue with the two sources?
ASKER CERTIFIED SOLUTION
Avatar of Charlie Arehart
Charlie Arehart

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
yeah there are settings on the IIS server that determine which protocols are used and in which order. I had dug all through that.  you can include or exclude the version of protocols you want to use. But hadn't considered that the API I was trying to use might require 1.2. Once I get emails back I will report what I find out.
Baub, it's very important to be clear about what "server" you're talking about, where you would check IIS. There is the server FROM WHICH you are making the API call, and the server TO WHICH you are making the call. I have been assuming all along that those are different, for you.

And if so, then to be clear, as for the server FROM WHICH the API call is happening, that IIS server is NOT AT ALL AN ISSUE, as such outgoing calls don't go THROUGH that IIS.

As for the server TO WHICH you are making the call, that may be IIS. We can't tell from the outside, usually. But again even if it IS, I'm saying that even that server TO WHICH you are making the call DOES let the TLS 1.1 call in, the thing it turns around and passes the API call to may NOT (like if it's a recent Java).

I'm just trying to help you keep all these variants in mind, and based on what info you have offered.
Ok, Just to close this out.  I contacted support at the API source and they replied that they didn't support TLS 1.1.  So now its in the hands of my software backend developer to add support for TLS 1.2.  So that was the issue the whole time.  Your support was very useful and helpful.   Thanks again!  Baub
Wonderful to hear (well, that the issue is now more clear for you, and that the assistance was helpful). It's one of those issues about which there can be lots to keep straight when trying to solve it. And then some problems do require others to step in and help you finally rectify. Sounds like you're on track there. Thanks for the kind regards, the points here, and the kind testimonial.

Hope things go smoothly going forward, but if not we should be here for you. :-)

Ok, I still haven't found a resolution to this problem.  Boo.


I'm wondering if I need to add something to my web.config file to force the use of a specific version of .net.

Or do I need to set something on the server that forces the site to use a specific version of TLS?


I've run out of ideas to test or a direction to persue?

So Baub, this is the 3rd time you've said it's not working after having said previously it was. :-) I'm sure that's very frustrating for you.


Help us out, though: when it "was" working (on july 20 and 25), can you confirm if you are talking about your trying some single URL (on your server) that is going between failing and working? Or are  you trying different URLs? 


1) First, let's be clear: I'm referring here to the URL you call in a browser, that runs on your server. It has seemed from the beginning that your issue is about calls OUT of your server, from within code in your app, right? 


2) Second, if it's in fact the SAME url you are calling (on your server), are you able to confirm that under the cover that is calling the SAME url (elsewhere), which works and sometimes? 


If so, then note that sometimes such failures (out of your server to another "same url" which "work sometimes and fail others") could be because of another possible issue on THAT server you are CALLING out to. For example, it may have a load balancer in front of it, such that sometimes your requests to it are ending up on DIFFERENT servers there (behind that load balancer), which you of course cannot control. It could be that THOSE have different TLS versions they support. I've seen it happen. 


But since you can't force your requests to go to a "good server" there, all you can do is try to gather evidence that sometimes your calls to them work and sometimes they fail. You could also try running a test against their server using some tool, which reports back to you what TLS version their server says it supports. You may find that "for the same url", you get back different results. 


(This is something you could do in your own code, checking the TLS communications, or with various 3rd party tools.  Just beware that some tools, like the free qualys ssl checker, work as a service--so the request is going from THEM to the URL you have them check. In any one request it makes, it could get a different result than YOU get. You'd need to check such a service multiple times.)


3) Finally, if what's "failing" for you are calls to different URLs (on your server) than those which you had been trying before, then sure: under the cover those could be themselves be calling out to different URLs elsewhere.  And perhaps some of those simply "fail" while others "work", for reasons unrelated to your server. You would want to check that to be sure.


BTW, you may be tempted to "try the failing URLs on the other server" from your own browser, but just beware that what you get back in browsing from your local workstation/laptop may be different than if you tried browsing the URLs (being called out to, on other servers) from a browser on your server (where your code is calling out to other servers)


I know that's a lot to consider. You seem to feel like you are "running out of ideas". Those are some to chew on. You may also want to re-read all the comments from July to now. You may "read" them differently with info you have gathered or I have shared since then. :-)


Let us know how it goes. Or perhaps someone will offer the magic bullet you seek, of a web.config change that might help. I just don't know of one for this issue.

1) First, let's be clear: I'm referring here to the URL you call in a browser, that runs on your server. It has seemed from the beginning that your issue is about calls OUT of your server, from within code in your app, right? 


That is correct it is a call out from our server.  I have tried the exact same API call on another server and it worked as it should.  I was also able to connect to the remote server via a http:// call ie no https:// on that side.


2) Second, if it's in fact the SAME url you are calling (on your server), are you able to confirm that under the cover that is calling the SAME url (elsewhere), which works and sometimes?   It is the same URL that it is calling to docspring.com.   I was able to set up another API at another site, basically a public open source site, I think just get weather or something type of API to test to make sure that that works and it does.


I have been able to connect to the API through postman.  So I know my login creds etc are correct.


After much trial and error (mostly error) I'm speculating that it is either TLS version problem, or perhaps a .net version problem.  


Here is the SSL report for the host I"m trying to attach to: docspring.com

https://www.ssllabs.com/ssltest/analyze.html?d=docspring.com&latest


And if def looks to maybe have a load balancer?


I thought that maybe it was the cipher that our server was using maybe?  I tried a bunch of different options there.  Tried to match the ciphers that host was using to what our server is configured to.  No luck there.


But like I said it will connect from a website that doesn't have SSL enabled.  So I kind of quit thinking in the vein of troubleshooting.


And the server I am coming from is maps.dockrealty.com


And I have to say once again thank you for all of the time you have put into this and the depth of your responses.



And thanks for your kind regards. :-)


1) So first, let me say that yes, there could be a tls cipher problem, or a tls algorithm problem, or a tls version problem, or a certificate bit-length problem, and so on. Any of those are possible explanations for why your server a calling to server b fails. There would seem to be something about what server b sends that server a rejects, or that server b requires that server a can't offer. That's certainly the ROOT cause problem.


And of course you will want to solve that. But we don't yet now WHAT that problem is, so we can't easily solve it.  And maybe someone will chime in with how to find it. 


1a) FWIW, if your app on server A was a Java app, I would know how to propose enabling Java to log the "tls handshake", and I'd know how to tell you where to find that log, and then how to interpret it. But since your server A is .net, I don't know how to do those things in .net. Again, perhaps someone else will...or that may be a clue you could use to find that info.


2) But back to what you shared in reply... 


a) I can confirm that for the ssl analyzer report for each of those 4 IP addresses, they did all report the same info (same tls, ciphers, etc.), so at least if we can trust that to be an authoritative confirmation, it doesn't seem you'd get different results from the different servers. We can't KNOW, but we can move on.


b) You refer to success using postman, but I'll say first that's like confirming that the request worked in your browser. If that postman is on your local machine, then it's not quite the "same" test. And second, how things work even from a browser "on the server" (the one running your .net app) can be different from how any browser or postman works. Each of those can have their own networking capabilities (including tls, etc.) that differ from what a .NET would have.


c) You refer to possibly changing (via config) what .net version your app uses. I had asked about .net versions back in July, above. What .net versions are available on your server? I had discussed how indeed some had different TLS versions they could or would support.


3) Indeed, as for possible solutions, let me note that I found a helpful SO post with several DIFFERENT ones to consider (different answers, with differing votes of success, each solving again different problems). Since we don't yet know what yours is, you should at least read it and decide if perhaps any are worth you trying. Some are code changes (changing the tls version used, whether raising or lowering it), while some are config file changes (such as controlling what .net version your app uses). Some are about certs and permissions issues related to those.


There's even a discussion there of what may be the equivalent to the handshake debugging, with the Microsoft Message Analyzer. But I don't know that I'd go to that first, if I were you. :-)


Let us know if you consider and try any of those (and perhaps confirm which don't work). The answer may be with one of those. 

I am attempting this now.  


https://stackoverflow.com/questions/2609859/how-to-give-asp-net-access-to-a-private-key-in-a-certificate-in-the-certificate


Wondering if it needs rights to the certificate.  I can RDP into the server at the hosting company but can't make the changes that this requires.  So I am waiting for hosting co to contact me back currently