Поделиться через


Including Self-Signed Certificates with your Windows Runtime based Windows Phone 8.1 apps

The concept of Universal apps lets you share common code targeting the Windows Runtime between a Windows Store app and a Windows Phone 8.1 app. However there are still some areas where there isn’t a 1:1 mapping. When using self-signed certificates with your Windows Runtime based Windows Phone 8.1 apps there is some complexity involved. This blog shows you how to reduce this complexity programmatically in your Windows Runtime based Windows Phone 8.1 project.

To give a brief background, with Windows Store apps targeting Windows 8.1, you as an app developer have the capability of including self-signed root certificates with your app so that you do not have to bypass server certificate validation errors accessing HTTPS URLs (not that I am saying that bypassing server certificates is a great idea :), and in fact you should never ignore server certificate errors).

With Windows Store apps targeting Windows 8.1, all you have to do to is to include your Root certificate with your app and add the “Certificate” Declaration to your Package.appxmanifest file like the below screenshot shows and the system will automatically take care of including this certificate in your apps Trusted Root certification store (not the Current User/ Local Computer store)

 

image

 

However, if you open your Package.appxmanifest file for Windows Phone 8.1 app (targeting the Windows Runtime, not the Silverlight Runtime), you will notice that the Declarations section is missing the option to add/include a Certificate.

image

 

The question is: How should you include self-signed root certificates with your Windows Phone 8.1 apps targeting the Windows Runtime?

The first step to include the self-signed root certificate with your Windows Phone 8.1 app (or a Universal app for that matter) is to include your certificate with your app and set the “Build Action” to “Content” as per the first image above.

Following this, you will need to install the root certificate using the below code – written in C# (the same applies for WinJS or C++) preferably during app startup or right before sending your very first HTTPs request to your target server (that uses a certificate issued by the root certificate authority you are trying to trust). In the below code example, the certificate is added inside the OnLaunched method of App.xaml.cs.

Note: The CertificateStore class only has Add and Delete methods (no query method), so adding the certificate multiple times does not throw any errors. Adding the certificate multiple times does not mean that there will be multiple copies of the certificate installed, there is only one copy of the certificate. You can verify this by calling Add method two times and subsequently calling Delete two times. You will notice that the second Delete call will throw an exception which states: "Cannot find object or property. (Exception from HRESULT: 0x80092004)". Also, the CertificateStores.FindAllAsync() method only returns you a list of certificates from the actual certificate store, and does not include/enumerate certificates from the TrustedRootCertificationAuthorities or IntermediateCertificationAuthorities store.

 

 protected async override void OnLaunched(LaunchActivatedEventArgs e)
 {
     // ...
     // ... other app startup code...
     // ...
  
     try
     {
         // Read the contents of the Certificate file
         System.Uri certificateFile = new System.Uri("ms-appx:///Assets/myRootCertificate.cer");
         Windows.Storage.StorageFile file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(certificateFile);
         Windows.Storage.Streams.IBuffer certBlob = await Windows.Storage.FileIO.ReadBufferAsync(file);
  
         // Create an instance of the Certificate class using the retrieved certificate blob contents
         Windows.Security.Cryptography.Certificates.Certificate rootCert = new Windows.Security.Cryptography.Certificates.Certificate(certBlob);
  
         // Get access to the TrustedRootCertificationAuthorities for your own app (not the system one)
         Windows.Security.Cryptography.Certificates.CertificateStore trustedStore = Windows.Security.Cryptography.Certificates.CertificateStores.TrustedRootCertificationAuthorities;
  
         // Add the certificate to the TrustedRootCertificationAuthorities store for your app
         trustedStore.Add(rootCert);
     }
     catch (Exception oEx)
     {
         // Catch and report exceptions
         System.Diagnostics.Debug.WriteLine("Exception Adding cert: " + oEx.Message);
     }
 }

 

Once you install your root certificate using the above code, you can then send a HTTPs request using the Windows.Web.Http.HttpClient class and not have to worry about ignoring server certificate errors and for what its worth, you should never ignore server certificate errors.

Hopefully this blog helps you understand how to include self-signed root certificates with your Windows Phone 8.1 app targeting the Windows Runtime and use them to trust your server certificate while negotiating a secure channel (HTTPs request).

Thanks to my teammate Eric Fleck (@EricThomasFleck) for providing his ideas to build the blog content…

Don’t forget to follow the Windows Store Developer Solutions team on Twitter @wsdevsol. Comments are welcome, both below and on twitter.

- Prashant H Phadke

Comments

  • Anonymous
    September 06, 2014
    Hi Prashant, Thanks for a great article! Could you please explain why Windows Phone's API doesn't provide an option to validate server certificate (something like System.Net.ServicePointManager#ServerCertificateValidationCallback)? Alex.

  • Anonymous
    September 18, 2014
    Hi Prashant, I have an issue during deployment, that is, the application certificate gets installed by default at "User > Intermediate Certification Authorities” where as after doing some research I found that the application checks the certificate at "Local Computer >Trusted Root Certification Authorities". We are doing SideLoading, for this app using the DISM command. Could you please advice as to how we can change the default location of the certificate using VS2013 else we will have to deploy the certificate using our CA, the path I do not wish to travel right now. Regards, AJ

  • Anonymous
    November 04, 2014
    Great article...

  • Anonymous
    November 05, 2014
    Great Post...But how to do it in windows phone 8.0

  • Anonymous
    December 01, 2014
    Hi Prashanth, Thanks for the great article. But the problem is adding the certificate is not working in Windows Phone 8.1 app. Is there any thing do i need to add to make it work. And can you please confirm me that have you tested this with Windows Phone 8.1.

  • Anonymous
    December 02, 2014
    Hi Prashanth, This is really a great job. I have tried this with the Windows Phone  silverlight 8.1 apps but it is not working. Is there any possibility to make it work in this platform. Please share your comments. Thanks in advance  

  • Anonymous
    December 29, 2014
    @Alex Lipov - The System.Net.ServicePointManager (SPM) class is only available for desktop apps. The System.Net classes on the desktop have their own HTTP Protocol implementation and is different from the "Silverlight" based classes available for the Phone which are based on WinINet based HTTP Protocol implementation. That's why you can't use the SPM class on the Phone @AJ - I am not quite sure how you can access the "Local Computer" store from a Windows Store app, can you clarify your scenario/situation further or use the MSDN forums to clarify your question? @Mukesh Pandey - These classes are only available for Windows Phone 8.1, they cannot be used on Windows Phone 8.0. @anil/ @nanu - Can you clarify what you mean by "it is not working"? What does not work? Adding the certificate using the code above or something else? I just tried adding a certificate using the code above to a "Windows Phone Silverlight 8.1" based project and I did not encounter any errors/exceptions.

  • Anonymous
    January 06, 2015
    Hi Prashant, is there a way to provide a client certificate to StreamSocket.ConnectAsync(EndpointPair, SocketProtectionLevel) ? I know this is not directly linked to this topic, but quite related. Any pointers will be really helpful. Thanks!

  • Anonymous
    April 08, 2015
    Thanks for the great article. Do you know how can I set ExclusiveTrust like WinRT in Windows Phone 8.1 RT?

  • Anonymous
    April 10, 2015
    @Kumar, you cannot use Client Certificates with Windows Runtime Sockets, StreamSocket class: msdn.microsoft.com/.../hh780595.aspx @Gulshan, since Windows Phone 8.1 does not expose a way to add the Certificates capability, you can't add the ExclusiveTrust attribute as well.

  • Anonymous
    April 13, 2015
    please, error accessing WP market store. Pleas analyze this info coming from my phone for me. Test Log // This log file describes test failures from the Production Self Test. // If you see this log file, it means that this device is not ready to ship // because some of the production self tests are failing. If this is a pre-production // device, this is an expected result and this file can be ignored (or deleted). If this // is supposed to be a production ready device, check the log below to identify tests that // are failing, and see the Windows Phone documentation for information on how to fix the // issues identified by these tests. TEST FAIL: BCD: Found banned Element BCDE_LIBRARY_TYPE_ALLOW_PRERELEASE_SIGNATURES TEST FAIL: UEFIVariable: SecureBoot is not enabled TEST FAIL: UEFIVariable: SetupMode IS enabled TEST FAIL: UEFIVariable: Unable to enumerate certificates in store 'db' TEST FAIL: UEFIVariable: Unable to enumerate certificates in store 'db' TEST FAIL: UEFIVariable: Unable to enumerate certificates in store 'PK' TEST FAIL: UEFIVariable: Unable to enumerate certificates in store 'KEK' TEST FAIL: UEFIVariable: Unable to read You: UEFI variable 'dbx' TEST FAIL: UEFIVariable: Unable to read UEFI variable 'PK' TEST FAIL: UEFIVariable: Unable to read UEFI variable 'KEK' TEST FAIL: SOC SelfTest failed. Details below. TEST FAIL: SOC Secure Boot Fuse has not been blown

  • Anonymous
    April 15, 2015
    The comment has been removed

  • Anonymous
    June 08, 2015
    Hi, i have done everything in this guide but i receive error 404 also if the certificate correctly install. Please help me!

  • Anonymous
    August 10, 2015
    What about Windows 8.1 apps(Tab etc.) ? Does this code useful for Windows 8.1 apps also? Also can you please guide how can we do same(trusting self signed cert from server) for windows 8 apps.

  • Anonymous
    October 26, 2015
    Hi , i have done all thing u mention but getting error 404. please help me to get response from https.

  • Anonymous
    October 27, 2015
    How can i generate a valid certificate? I do the steps above but the issue keep occurring.

  • Anonymous
    February 08, 2016
    Hi Prasant, How can we validate server certificate in Windows Phone 8.1 ?

  • Anonymous
    March 15, 2016
    The comment has been removed