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)
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.
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, AJAnonymous
November 04, 2014
Great article...Anonymous
November 05, 2014
Great Post...But how to do it in windows phone 8.0Anonymous
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 advanceAnonymous
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 blownAnonymous
April 15, 2015
The comment has been removedAnonymous
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