在Windows 8.1电话应用程序上固定的“独家信任”证书

时间:2016-04-19 14:16:53

标签: ssl windows-phone-8 ssl-certificate pinning

所以我正在尝试开发一个安全的Windows 8.1手机应用程序。请注意,这适用于Windows Phone,而不适用于普通Windows。这里主要关注的是中间人(MITM)攻击。

该应用程序是使用Microsoft App Studio(http://appstudio.windows.com/)生成的,并使用Visual Studio 2015进行了编辑。

我可以使用此MS博文上的说明将证书固定到正常的Windows部分:https://blogs.msdn.microsoft.com/wsdevsol/2014/06/05/including-self-signed-certificates-with-your-windows-runtime-based-windows-phone-8-1-apps/但问题是用户可以将证书上传到设备,该证书将覆盖此应用的支票。< / p>

此方法的问题在于,Windows Phone应用程序的Package.appxmanifest界面不允许您更新证书,更不用说将其标记为“独占”。

我的第二次尝试是根据这篇文章硬编码服务器证书的指纹:https://blogs.windows.com/buildingapps/2015/10/13/create-more-secure-apps-with-less-effort-10-by-10/(注意“独家信任”的复选框)

虽然该帖子适用于Windows 10,但代码仍有效(添加适当的导入后)。但是,当一个人更新自己的证书时,它会绕过指纹检查。

因为我无法使用Visual Studio界面将证书上传到Phone App部分,因此无法选中“Exclusive Trust”复选框,我将如何确保只对网站发出任何请求使用我上传的证书或指纹硬编码?

这是指纹识别码:

using System;
using System.Net;
using Windows.Web.Http;
using System.Collections.Generic;
using Windows.System;
using Windows.Security.Cryptography.Certificates;
using The_App.Views;

namespace The_App.Services
{
    public class NavigationServices
    {
        static public void NavigateToPage(string pageName, object parameter = null)
        {
            try
            {
                string pageTypeName = String.Format("{0}.{1}", typeof(MainPage).Namespace, pageName);
                Type pageType = Type.GetType(pageTypeName);
                App.RootFrame.Navigate(pageType, parameter);
            }
            catch (Exception ex)
            {
                AppLogs.WriteError("NavigationServices.NavigateToPage", ex);
            }
        }

        static public async void NavigateTo(Uri uri)
        {
            try
            {
                // Send a get request to uri
                HttpClient client = new HttpClient();
                HttpResponseMessage response = await client.GetAsync(uri);

                // Get the list of certificates that were used to validate the server's identity
                IReadOnlyList<Certificate> serverCertificates = response.RequestMessage.TransportInformation.ServerIntermediateCertificates;

                // Perform validation
                if (!ValidCertificates(serverCertificates))
                {
                    // Close connection as chain is not valid
                    return;
                }

                // PrintResults("Validation passed\n");
                // Validation passed, continue with connection to service
                await Launcher.LaunchUriAsync(uri);
            }
            catch (Exception ex)
            {
                AppLogs.WriteError("NavigationServices.NavigateTo", ex);
            }
        }

        private static bool ValidCertificates(IReadOnlyList<Certificate> certs)
        {
            // In this example, we iterate through the certificates and check that the chain contains
            // one specific certificate we are expecting
            for (int i = 0; i < certs.Count; i++)
            {
                // PrintResults("Cert# " + i + ": " + certs[i].Subject + "\n");
                byte[] thumbprint = certs[i].GetHashValue();

                // Check if the thumbprint matches whatever you are expecting
                // <The SHA1 Server Certificate HEX Number in the comments>
                byte[] expected = new byte[] { <The SHA1 Server Certificate Number in Bytes 45, 15, etc.> };

                if (thumbprint == expected)
                {
                    return true;
                }
            }

            return false;
        }

    }
}

0 个答案:

没有答案