Reputation: 21
I would like to share my experience of making requests with a self-signed certificate in the MAUI .NET 7 app (specifically for the Android part).
The original problem comes from AndroidMessageHandler.ClientCertificates that are not initialized (null) in MAUI .NET 7 when native AndroidMessageHandler is used.
In application used self-signed certificates with private key generation based on RSA standard functionality that is in .NET 7 (For .NET 6 you could use the BouncyCastle NuGet package to archive that)
I could find only one suggestion without a working solution for that problem https://github.com/xamarin/xamarin-android/issues/7274 (though it was for Xamarin Android, but used like ignition for me)
so in order to make it work here is the steps:
that's all, if you like I could also place a working code
sharing my experience with developers as there is no working solution as of Match 2023
Upvotes: 2
Views: 2374
Reputation: 444
For Android, this post does it.
For iOS, I do it like this. In Info.plist add
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>YOUR_HOST_HERE</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
In the code, do
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
Note that your .pem file should be in Resources/Raw as a MauiAsset.
Upvotes: 0
Reputation: 3907
I have different solution.
Load all certificates from the chain in KeyStore.
Init TrustManagerFactory with the KeyStore.
Init SSLContext with that TrustManagerFactory.
Create new SSLSocketFactory, using that SSLContext. Key part of this process, is the injection of the hostname and address, in the method for creating sockets.
Create Socket, and set additional parameters (Timeout, EnabledProtocols <<< really important, ClientMode, etc...)
Handshake.
Upvotes: 1