Answered How to discard certificate validation in HttpWebRequest

  • Friday, June 22, 2012 11:08 AM
     
     

    Hi,

    I have a Windows 8 Metro C# Code which sends HTTP POST to a HTTPS URL.

    I know that the certificate is invalid/expired. I want to discard the certificate validation. Can anyone suggest me how to do discard certificate validation.

    The exception I am getting is

    Exception thrown is: System.Net.WebExceptionStatus.TrustFailure             

    Exception Details: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

    My code looks like this:

    public sealed partial class BlankPage1 : Page

    {

    private static ManualResetEvent allDone = new ManualResetEvent(false);

    private async void Button_Click_1(object sender, RoutedEventArgs e)

      {

    string url = "https://100.100.100.100/page.html";

                                         

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

    request.ContentType = "application/x-www-form-urlencoded";

    request.Method = "POST";

    request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);

    allDone.WaitOne();

      }

    private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)

      {

    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

           Stream postStream = request.EndGetRequestStream(asynchronousResult);

    string postData = "Sample data to post";

           byte[] byteArray = Encoding.UTF8.GetBytes(postData);

           // Write to the request stream.

           postStream.Write(byteArray, 0, postData.Length);

           postStream.Dispose();

           // Start the asynchronous operation to get the response

    request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);

      }

    private static void GetResponseCallback(IAsyncResult asynchronousResult)

      {

    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

           //====================================================================

           // Exception is thrown on the below line

           // Exception is: System.Net.WebExceptionStatus.TrustFailure

           // Exception Details: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

           //====================================================================

    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);

    Stream streamResponse = response.GetResponseStream();

    StreamReader streamRead = new StreamReader(streamResponse);

    string responseString = streamRead.ReadToEnd();

    streamResponse.Dispose();

    streamRead.Dispose();

    response.Dispose();

           allDone.Set();

      }

    }

    Regards,

    A.JohnPaul

All Replies

  • Friday, June 22, 2012 11:43 AM
     
     
    Hey the easiest way is to open the https page in IE, have a look at the certificate, then "Install Certificate" to Trusted People store.

    Can Bilgin
    Blog CompuSight

  • Friday, June 22, 2012 2:12 PM
     
     

    Hi,

    I would like to achieve this through the code.

    Can you please share some thoughts on how it can be achieved through code.

    Regards,

    A.JohnPaul


    A. John Paul

  • Friday, June 22, 2012 6:03 PM
     
     
    I would look for the SslStream class in metro documentation there is an example with validationcallback.

    Can Bilgin
    Blog CompuSight

  • Sunday, June 24, 2012 3:31 PM
     
     

    Hi,

    Can you please share the sample code of SslStream class with with validationcallback.

    Regards,

    A.JohnPaul


    A. John Paul

  • Sunday, June 24, 2012 3:36 PM
     
     
    here: http://msdn.microsoft.com/en-us/library/windows/apps/system.net.security.sslstream%28v=vs.110%29.aspx have a look at the last example and the function ValidateServerCertificate... You can just return true in this function mask any certificate errors. This example is using a tcp client but I guess you can do the same with an http client.

    Can Bilgin
    Blog CompuSight

  • Monday, June 25, 2012 5:18 AM
     
     

    Hi,

    I tried the code given in the above URL. This code is not working in Windows 8 Metro Style Apps. The following import statements are showing compiler errors.

    using System.Net.Security;
    using System.Net.Sockets;
    using System.Security.Authentication;
    using System.Security.Cryptography.X509Certificates;

    Error 1 The type or namespace name 'Security' does not exist in the namespace 'System.Net' (are you missing an assembly reference?) D:\HTTPSSample\HTTPSSample\BlankPage1.xaml.cs 20 18 HTTPSSample
    Error 2 The type or namespace name 'Sockets' does not exist in the namespace 'System.Net' (are you missing an assembly reference?) D:\HTTPSSample\HTTPSSample\BlankPage1.xaml.cs 21 18 HTTPSSample
    Error 3 The type or namespace name 'Authentication' does not exist in the namespace 'System.Security' (are you missing an assembly reference?) D:\HTTPSSample\HTTPSSample\BlankPage1.xaml.cs 22 23 HTTPSSample
    Error 4 The type or namespace name 'Cryptography' does not exist in the namespace 'System.Security' (are you missing an assembly reference?) D:\HTTPSSample\HTTPSSample\BlankPage1.xaml.cs 23 23 HTTPSSample
    Error 5 The type or namespace name 'Hashtable' could not be found (are you missing a using directive or an assembly reference?) D:\HTTPSSample\HTTPSSample\BlankPage1.xaml.cs 148 24 HTTPSSample

    Any other idea please?

    Regards,

    A.JohnPaul


    A. John Paul

  • Wednesday, June 27, 2012 3:23 PM
    Moderator
     
     Answered

    Hi A.JohnPaul,

    You cannot ignore certificate errors.  The server must provide a valid certificate.

    -Jeff


    Jeff Sanders (MSFT)

  • Thursday, June 28, 2012 7:01 AM
     
     

    Hi Jeff Sanders,

    Thank you for your information.

    If you come to know any other way to ignore certificate errors. Please let me know.

    Regards,

    A.JohnPaul


    A. John Paul

  • Thursday, July 12, 2012 8:00 PM
    Moderator
     
     Proposed Answer
    You never have to ignore them.  You can just fix your test machine so your cert is in the trusted root of the Machine store!

    Jeff Sanders (MSFT)

  • Friday, July 13, 2012 5:45 AM
     
     

    Through code, is it possible to store the invalid certificate in trusted root of Machine store.

    Regards,

    A.JohnPaul


    A. John Paul

  • Friday, July 13, 2012 2:25 PM
    Moderator
     
     Proposed Answer Has Code

    Absolutely!

    http://msdn.microsoft.com/en-us/library/windows/apps/hh464981.aspx#certificates_extension_sample_1

    You can include the server cert (and any intermediate certs) in your app and through the certificate extensions, set that cert in code.

    1. Export the server cert to a .der file

    2. Include the cert in your application (I put mine in the Assets Directory)

        Right click on the cert after you include it in your project and

         a. set the Build Action to Content

         b. set the Copy to Output Directory to Copy always

    3.  Open the package.appxmanifest in the text or XML editor by right clicking on it and add your cert to the "Root"

    </Capabilities>
      <Extensions>
        <!--Certificates Extension-->
        <Extension Category="windows.certificates">
          <Certificates>
            <Certificate StoreName="Root" Content="Assets\jsanders4.cer" />
            
          </Certificates>
        </Extension>
      </Extensions>

    Note:  This is the trusted root store for this application only (for obvious security reasons).

    -Jeff


    Jeff Sanders (MSFT)


  • Sunday, September 02, 2012 2:39 AM
     
      Has Code

    Absolutely!

    http://msdn.microsoft.com/en-us/library/windows/apps/hh464981.aspx#certificates_extension_sample_1

    You can include the server cert (and any intermediate certs) in your app and through the certificate extensions, set that cert in code.

    1. Export the server cert to a .der file

    2. Include the cert in your application (I put mine in the Assets Directory)

        Right click on the cert after you include it in your project and

         a. set the Build Action to Content

         b. set the Copy to Output Directory to Copy always

    3.  Open the package.appxmanifest in the text or XML editor by right clicking on it and add your cert to the "Root"

    </Capabilities>
      <Extensions>
        <!--Certificates Extension-->
        <Extension Category="windows.certificates">
          <Certificates>
            <Certificate StoreName="Root" Content="Assets\jsanders4.cer" />
            
          </Certificates>
        </Extension>
      </Extensions>

    Note:  This is the trusted root store for this application only (for obvious security reasons).

    -Jeff


    Jeff Sanders (MSFT)


    Does this work for self-signed certs?  Because I still get a HttpRequestException that the says it failed the trust validation.  And the cert is not installed on the device.
  • Tuesday, September 04, 2012 11:35 AM
    Moderator
     
     Proposed Answer
    Yes it does (jsanders4.cer is a self signed cert for my IIS server)!  If you have a validation chain you would also include any cert in that chain.

    Jeff Sanders (MSFT)

  • Friday, September 07, 2012 7:17 AM
     
     

    Hi,

    Thanks for your suggestion. It works!.

    I am facing a new problem now.

    In my code, I am contacting many local servers in my LAN. And all the servers are having invalid certificate. I would like to avoid manual process of exporting/importing the certificate and updating the manifest file. Is there any way where I can automate all the above three points through code.

    Regards,

    John


    A. John Paul

  • Friday, September 07, 2012 11:44 AM
    Moderator
     
     Proposed Answer

    Hi John,

    Let's take a step back.  If you are using HTTPS for security, and the number of servers is not static and all of these servers have certificates that are not valid, why would you bother using HTTPS to begin with?  It would be incredibly easy for someone to spoof an address and intercept all your traffic!  Certificate verification is very important to ensure your HTTP server is indeed secure - HTTP(S).  Also HTTP traffic will be faster that HTTPS traffic since you really don't care to verify the authenticity of the server.  See if you can convince your network admin to abandon HTTPS or get valid certificates for these servers.

    That said...  If you really want to do this, the easiest way is to set the 'many' servers up signed with a root certificate authority (could be your own) and trust that root certificate.  At least then you could install the root cert with the manifest and trust that.  Make sense?

    -Jeff


    Jeff Sanders (MSFT)

  • Friday, September 28, 2012 11:30 AM
     
     

    I have read your post, it helps me a lot ,but currently I still can't make https work on my metro apps.

    The Environment is 

    Server: Ubuntu Server 12.04, Web Server: Mongoose

    Client: Windows 8 

    And I have a key in pem format installed on server, I can access the web page through browser, but browser just said the certificate can't be trusted, and I transfer the pem file to der file with openssl, and include the der file in Visual studio solution, I still can't send https request successfully.

    Could you give a more detailed instructions? thank you very much.

  • Friday, September 28, 2012 11:51 AM
    Moderator
     
     Proposed Answer

    Use Internet Explorer to access your https site.  Trust the certificate and go to the page.  Then Export then view and export the server certificate by hitting the little icon that look like a lock.  Then use that cert in the instructions above.


    Jeff Sanders (MSFT)

  • Thursday, October 11, 2012 3:17 PM
     
     

    Hi Jeff,

    Please help me , if suppose I had a invalid certificate if that case can metro app accept and continue with the website as its done in browser ?

    regards,

    Joy

  • Thursday, October 11, 2012 6:43 PM
    Moderator
     
     Proposed Answer
    No, there is no way to explicitly do that.

    Jeff Sanders (MSFT)

  • Wednesday, October 17, 2012 5:13 AM
     
     

    thanks Jeff

    regards,

    joy