だから私は安全な Windows 8.1 Phone アプリを開発しようとしています。これは Windows Phone 用であり、通常の Windows 用ではないことに注意してください。ここでの主な懸念事項は、中間者 (MITM) 攻撃です。
アプリは Microsoft App Studio ( http://appstudio.windows.com/ ) を使用して生成され、Visual Studio 2015 を使用して編集されました。
この MS ブログ投稿 ( https://blogs.msdn.microsoft.com/wsdevsol/2014/06/05/include-self-signed-certificates-with-your- ) の手順を使用して、証明書を通常の Windows セクションに固定できますwindows-runtime-based-windows-phone-8-1-apps/ ですが、問題は、ユーザーがこのアプリからのチェックを上書きする証明書をデバイスにアップロードできることです。
このアプローチの問題点はPackage.appxmanifest
、Windows Phone アプリのインターフェイスでは、証明書を「排他的」としてマークするどころか、証明書を更新できないことです。
私の 2 番目の試みは、この投稿に従ってサーバー証明書のフィンガープリントをハードコーディングすることでした: https://blogs.windows.com/buildingapps/2015/10/13/create-more-secure-apps-with-less-effort-10 -by-10/ (「排他的信頼」のチェックボックスに注意してください)
投稿は Windows 10 用ですが、コードは機能しました (適切なインポートを追加した後)。ただし、ここでも、自分の証明書を更新すると、フィンガープリント チェックがバイパスされます。
Visual Studio インターフェイスを使用して電話アプリ パーツに証明書をアップロードできず、[排他的信頼] のボックスをオンにできないため、Web サイトへの要求で証明書のみが使用されるようにするにはどうすればよいでしょうか。アップロードしますか、それとも指紋をハードコードしますか?
フィンガープリントコードは次のとおりです。
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;
}
}
}