MAUI .NET 7 - 如何使用应用程序中的自签名证书发出 http 请求

问题描述 投票:0回答:2

我想分享一下我在 MAUI .NET 7 应用程序中使用自签名证书发出请求的经验(特别是针对 Android 部分)。

最初的问题来自于使用本机 AndroidMessageHandler 时在 MAUI .NET 7 中未初始化 (null) 的 AndroidMessageHandler.ClientCertificates。

在应用程序中使用自签名证书,并基于 .NET 7 中的 RSA 标准功能生成私钥 (对于 .NET 6,您可以使用 BouncyCastle NuGet 包来存档)

我只能找到一个建议,但没有解决该问题的可行方案 https://github.com/xamarin/xamarin-android/issues/7274 (虽然它是针对 Xamarin Android 的,但对我来说就像点火一样)

因此,为了使其在这里工作,请执行以下步骤:

  1. 添加继承自AndroidMessageHandler的自定义消息处理程序
  2. 在构造函数中初始化 ClientCertificates 并向其添加自签名证书
  3. 为ConfigureKeyStore、ConfigureKeyManagerFactory 和ConfigureTrustManagerFactory 添加以下覆盖
  4. 在ConfigureKeyStore 将自签名证书和私钥导入到新创建的KeyStore 中(这里您需要从.NET RSA 内容制作一个java 证书 - 我可以提供代码)。这是在 HTTP 请求中获取证书的重要步骤之一
  5. 您还需要在构造函数中提供 ServerCertificateCustomValidationCallback,以便您可以处理 SslPolicyErrors.RemoteCertificateChainErrors,因为证书是自签名的

仅此而已,如果您愿意,我还可以放置一个工作代码

与开发者分享我的经验,因为截至 2023 年比赛还没有可行的解决方案

maui x509certificate2 self-signed-certificate
2个回答
1
投票

我有不同的解决方案。

  1. 从KeyStore中的链中加载所有证书。

  2. 使用 KeyStore 初始化 TrustManagerFactory。

  3. 使用 TrustManagerFactory 初始化 SSLContext。

  4. 使用该 SSLContext 创建新的 SSLSocketFactory。此过程的关键部分是在创建套接字的方法中注入主机名和地址。

  5. 创建Socket,并设置附加参数(Timeout、EnabledProtocols <<< really important, ClientMode, etc...)

  6. 握手。


0
投票

对于 Android,这篇文章 可以做到。

对于iOS,我是这样做的。 在Info.plist中添加

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>YOUR_HOST_HERE</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>

在代码中,执行

X509Certificate2 clientCertificate = new X509Certificate2();
try
{
  using(Stream cs = await FileSystem.Current.OpenAppPackageFileAsync(YOUR_PEM_FILE_NAME))
  {
    Byte[] raw = new Byte[cs.Length];
    for (Int32 i = 0; i < cs.Length; ++i)
      raw[i] = (Byte)cs.ReadByte();
     clientCertificate = new X509Certificate2(raw, YOUR_PWD, X509KeyStorageFlags.DefaultKeySet);
  }
}
catch(Exception e)
{
  //whatever
}
var handler = new NSUrlSessionHandler();
handler.TrustOverrideForUrl = (session, url, trust) => 
{
  var uri = new Uri(url);
  var ok = uri.Host switch
    {
      "YOUR_HOST_HERE" => true,
      _ => false
    };
    if (!ok) return false;
    trust.SetAnchorCertificates(new X509Certificate2Collection(clientCertificate));
    NSError error;
    var trustCertificate = trust.Evaluate(out error);
    if (error is not null)
    {
       //whatever
    }
    return trustCertificate;
};
var httpClient = new (handler);
//Do as usual with the httpClient

请注意,您的 .pem 文件应作为 MauiAsset 位于 Resources/Raw 中。

© www.soinside.com 2019 - 2024. All rights reserved.