Repository navigation
App crashes when using SHA1.Create() under NativeAOT #10463
Description
Activity
- addedArea: App RuntimeIssues in `libmonodroid.so`.Issues in `libmonodroid.so`.needs-triageIssues that need to be assigned.Issues that need to be assigned.
on Sep 2, 2025 App startup needs to invoke
AndroidCryptoNative_InitLibraryOnLoad, defined inlibSystem.Security.Cryptography.Native.Android.a.Question: how do we do that?
Which appears to be for CoreCLR and not NativeAOT…
The binlog contains:
Target "SetupOSSpecificProps: Added Item(s): DirectPInvoke= System.Native System.Globalization.Native System.IO.Compression.Native System.Security.Cryptography.Native.AndroidSystem.Security.Cryptography.Native.Androidpresumably meaninglibSystem.Security.Cryptography.Native.Android.a, which containsAndroidCryptoNative_InitLibraryOnLoad.This is later transformed within the
WriteIlcRspFileForCompilationtarget intoilcparameters:Added Item(s): IlcArg= --directpinvoke:System.Native --directpinvoke:System.Globalization.Native --directpinvoke:System.IO.Compression.Native --directpinvoke:System.Security.Cryptography.Native.AndroidWhich become part of a
.ilc.rspfile.What I find interesting are two things:
First, the regulating
.ofile contains no symbols fromlibSystem.Security.Cryptography.Native.Android.a. This suggests thatlibSystem.Security.Cryptography.Native.Android.aisn't actually being used.Second, I'm not sure how
ilcis supposed to findlibSystem.Security.Cryptography.Native.Android.a. There is no real "tying" ofSystem.Security.Cryptography.Native.Androidto a filesystem location forlibSystem.Security.Cryptography.Native.Android.a. That is,libSystem.Security.Cryptography.Native.Android.ais:$HOME/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-arm64/10.0.0-rc.2.25420.109/runtimes/android-arm64/native/libSystem.Security.Cryptography.Native.Android.abut of the values within
.ilc.rspthat contain absolute paths:-r:$HOME/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25420.109/runtimes/android-x64/native/System.Private.CoreLib.dll -r:$HOME/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25420.109/runtimes/android-x64/native/System.Private.Reflection.Execution.dll -r:$HOME/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25420.109/runtimes/android-x64/native/System.Private.StackTraceMetadata.dll -r:$HOME/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25420.109/runtimes/android-x64/native/System.Private.TypeLoader.dll … --descriptor:…/dotnet/android/bin/Debug/lib/packs/Microsoft.Android.Sdk.Darwin/36.0.0/PreserveLists/Java.Interop.xml --descriptor:…/dotnet/android/bin/Debug/lib/packs/Microsoft.Android.Sdk.Darwin/36.0.0/PreserveLists/Mono.Android.Runtime.xml --descriptor:…/dotnet/android/bin/Debug/lib/packs/Microsoft.Android.Sdk.Darwin/36.0.0/PreserveLists/Mono.Android.xml --descriptor:…/dotnet/android/bin/Debug/lib/packs/Microsoft.Android.Sdk.Darwin/36.0.0/PreserveLists/System.Runtime.InteropServices.xml --descriptor:…/dotnet/android/bin/Debug/lib/packs/Microsoft.Android.Sdk.Darwin/36.0.0/PreserveLists/System.Runtime.xmlNone look like a straightforward way to find
libSystem.Security.Cryptography.Native.Android.a, unless you wanted to do various../../../…path probing logic against the various-rvalues.Looking at
ilc --helpoutput, I'm not sure I see anything that screams "path to.ato include in output". How is--directpinvokesupposed to work?DirectPInvoke just means "when I have a DllImport to the specified library!symbol, don't generate code that tries to dlopen/dlsym this at runtime; instead generate a symbol reference and let the linker (native linker, not "our IL linker") deal with it.
I think what you need is in dotnet/runtime#108513 that didn't merge yet?
DirectPInvoke just means "when I have a DllImport to the specified library!symbol, don't generate code that tries to dlopen/dlsym this at runtime; instead generate a symbol reference and let the linker (native linker, not "our IL linker") deal with it.
This is enlightening, and answers a conceptual question I had.
It is thus possible to workaround this issue:
Firstly, .NET 10 Preview 7 cannot be used. .NET 10 RC1 or later is required. A newer .NET 10 is required so that
libSystem.Security.Cryptography.Native.Android.aexists and is used at build time, instead oflibSystem.Security.Cryptography.Native.OpenSsl.so, which cannot work on Android.If you don't mind building dotnet/android, use dotnet/android@3ed06827 or later.
Using a custom dotnet/android build in turn requires a custom
NuGet.configfile so that various dependencies can be found.Additionally,
AndroidCryptoNative_InitLibraryOnLoad()must be invoked. This requires three separate changes:-
Add a P/Invoke to
System.Security.Cryptography.Native.Android!AndroidCryptoNative_InitLibraryOnLoad -
Add an
Applicationsubclass which invokesAndroidCryptoNative_InitLibraryOnLoad(). -
Update the
.csprojto add a@(DirectPInvoke)which tellsilc
"when you see a P/Invoke toAndroidCryptoNative_InitLibraryOnLoad, turn it into a function invocation."<ItemGroup> <DirectPInvoke Include="System.Security.Cryptography.Native.Android!AndroidCryptoNative_InitLibraryOnLoad" /> </ItemGroup>
The syntax is
LIBRARY!SYMBOL, andLIBRARYmust match the P/Invoke library declaration, and
SYMBOLmust match the P/Invoke method name.
The above three steps correspond to the following patch to Scratch.net10-android-sha1-create.zip:
diff --git a/MainActivity.cs b/MainActivity.cs index 634ae50..936e3be 100644 --- a/MainActivity.cs +++ b/MainActivity.cs @@ -1,5 +1,9 @@ +using System.Runtime.InteropServices; using System.Security.Cryptography; +using Android.Runtime; +using Java.Interop; + namespace Scratch.net10_android_sha1_create; [Activity(Label = "@string/app_name", MainLauncher = true)] @@ -15,4 +19,29 @@ public class MainActivity : Activity // Set our view from the "main" layout resource SetContentView(Resource.Layout.activity_main); } -} \ No newline at end of file +} + +[Application] +public class MyApp : Application +{ + public MyApp(IntPtr handle, JniHandleOwnership transfer) + : base(handle, transfer) + { + } + + public override void OnCreate() + { + base.OnCreate(); + IntPtr invocationPointer; + JniEnvironment.References.GetJavaVM(out invocationPointer); + UnsafeNativeMethods.AndroidCryptoNative_InitLibraryOnLoad( + javaVM: invocationPointer, + reserved: IntPtr.Zero); + } +} + +static class UnsafeNativeMethods +{ + [DllImport("System.Security.Cryptography.Native.Android", CallingConvention = CallingConvention.Cdecl)] + internal static extern void AndroidCryptoNative_InitLibraryOnLoad(IntPtr javaVM, IntPtr reserved); +} diff --git a/Scratch.net10-android-sha1-create.csproj b/Scratch.net10-android-sha1-create.csproj index b816b61..51b728a 100644 --- a/Scratch.net10-android-sha1-create.csproj +++ b/Scratch.net10-android-sha1-create.csproj @@ -22,4 +22,7 @@ --> <TrimMode>full</TrimMode> </PropertyGroup> + <ItemGroup> + <DirectPInvoke Include="System.Security.Cryptography.Native.Android!AndroidCryptoNative_InitLibraryOnLoad" /> + </ItemGroup> </Project> \ No newline at end of file
With those changes in place, Publish and run the app:
…/dotnet-local.sh publish -c Release -p:PublishAot=true -t:Install,StartAndroidActivity -blYou know it works properly when
AndroidCryptoNative_InitLibraryOnLoadis present in the native library:% nm bin/Release/net10.0-android/android-arm64/native/Scratch.net10-android-sha1-create.so | grep AndroidCryptoNative_InitLibraryOnLoad 00000000001d34f0 t AndroidCryptoNative_InitLibraryOnLoad 000000000027ef10 t Scratch_net10_android_sha1_create_Scratch_net10_android_sha1_create_UnsafeNativeMethods__AndroidCryptoNative_InitLibraryOnLoad 0000000000010a2b r _lsda0Scratch_net10_android_sha1_create_Scratch_net10_android_sha1_create_UnsafeNativeMethods__AndroidCryptoNative_InitLibraryOnLoad-
- added 8 commits that reference this issue
on Sep 11, 2025 9 remaining items
- added 12 commits that reference this issue
on Oct 3, 2025 This has been fixed in .NET 10 RC2, in that the workaround is no longer required.
- locked and limited conversation to collaborators
on Nov 20, 2025
Android framework version
net10.0-android (Preview)
Affected platform version
.NET 10 Preview 7, bf02f562
Description
Invoking e.g.
SHA1.Create()results in app abort.Steps to Reproduce
Build and run the attached sample:
Scratch.net10-android-sha1-create.zip
unzip Scratch.net10-android-sha1-create.zip cd Scratch.net10-android-sha1-create dotnet build -c Release -p:PublishAot=true -t:Install,StartAndroidActivity -blDid you find any workaround?
No response
Relevant log output