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 (18)

  1. Alex Lipov says:

    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.

  2. AJ says:

    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

  3. Dimple Sharma says:

    Great article…

  4. Mukesh Pandey says:

    Great Post…But how to do it in windows phone 8.0

  5. anil says:

    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.

  6. nanu says:

    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  

  7. Prashant H Phadke says:

    @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.

  8. Kumar says:

    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!

  9. Gulshan says:

    Thanks for the great article. Do you know how can I set ExclusiveTrust like WinRT in Windows Phone 8.1 RT?

  10. @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.

  11. elvis says:

    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

  12. Artax says:

    Hello,

    I have an error with this code.

    It's about the line : Windows.Storage.StorageFile file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(certificateFile);

    The error is : The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

    Can u help me ?

  13. Vittorio says:

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

  14. Sapna says:

    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.

  15. sanjay says:

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

  16. Vinicius says:

    How can i generate a valid certificate? I do the steps above but the issue keep occurring.

  17. Raja says:

    Hi Prasant,

    How can we validate server certificate in Windows Phone 8.1 ?

  18. Frank Walsh says:

    I followed these instructions precisely, the certificate appears to be added correctly…but my Windows.System.Launcher.LaunchUriAsync(uri); call doesn't run…I don't get any errors adding the certificate…but I can tell you that dispite adding it to the trust store…edge. still says it's invalid.. IE says it's valid… chrome says: The server did not supply any Certificate Transparency Information, the certificate for this site expires in 2017 or later and the certificate chain contains a certificate signed using SHA-1.

    Can you tell me what the requirements of a certificate are for Windows Universal? Or any other ideas as to why it isn't working?

    Thanks,

    Frank

Skip to main content