0

I have the following working code. This only works when the server is localhost or a remote server only with HTTP. But it falls when I tired with HTTPS. I don't know how to make a post/get request to HTTPS server. I know it involves SSL certification. This whole SSL and certification stuff is completely new to me. So I tried few options as follows. So I tried to add a generate a self-signed certificate. I made the certificate by the following command:-

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privatekey.key -out certificate.crt

I don't know do I need to generate this certificate at client side or at the server side? I am guessing it should be from Serer side. I am not sure. I tried both from server and client. I get similar error.

private HttpClient GetHttpClient(Uri baseAddress, string path, string apiKey)
        {
            try
            {
                // The path to the certificate.
                string Certificate = "Certificate.crt";
                X509Certificate cert = new X509Certificate(Certificate);
                string resultsTrue = cert.ToString(true);
                WebRequestHandler webRequestHandler = new WebRequestHandler();
                webRequestHandler.ClientCertificates.Add(cert);
                var client = new HttpClient(webRequestHandler);
                client.BaseAddress = baseAddress;
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));

                byte[] key = Convert.FromBase64String(apiKey);
                byte[] pathBytes = Encoding.ASCII.GetBytes(path);
                byte[] hash = Hash(key, pathBytes);
                string encoded = Base64UrlEncode(hash);
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", encoded);
                return client;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
        }

  private async Task<Stream> GetDataAsync(HttpClient client, string path)
        {
            HttpResponseMessage response = null;
            try
            {
                string url = jsonParser.StringBaseAddress + path;
                response = await client.GetAsync(url);
            }
            catch (Exception ex)
            {
                 Console.WriteLine("Msg: "+ex.Message);
                 Console.WriteLine("InnerException. "+ex.InnerException);
            }  
     }

When I made call it. I get following exception:-

Msg: An error occurred while sending the request. InnerException. System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure. at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) --- End of inner exception stack trace --- at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)

How can I make http get/post call to HTTPS server?

masiboo
  • 4,537
  • 9
  • 75
  • 136
  • Possible duplicate of [Could not establish trust relationship for SSL/TLS secure channel -- SOAP](https://stackoverflow.com/questions/703272/could-not-establish-trust-relationship-for-ssl-tls-secure-channel-soap) – RMH Feb 24 '18 at 16:48
  • The certificate goes on the server. The HttpClient should (by itself) already check your local keystore for validating the server certificate if the server returns it. Your error message states that it might be invalid (see the above post how to determine what is wrong). – RMH Feb 24 '18 at 16:58
  • It's not clear if you need a certificate or not. If not explicitly required by the server (you would know) you just need to enable the required Tls protocol (usually Tls 1.2 => `ServicePointManager.SecurityProtocol`) and validate the server certificate. For this, you need to register a `ServicePointManager.ServerCertificateValidationCallback`. You can just return `true` in the callback if a certificate is not required on your side. See the linked duplicate. [This (using HttpWebRequest) is mine](https://stackoverflow.com/questions/48589590/which-tls-version-was-negotiated/48675492#48675492). – Jimi Feb 24 '18 at 18:41

0 Answers0