Nethereum.WebAuthn.Windows
7.0.0
Prefix Reserved
dotnet add package Nethereum.WebAuthn.Windows --version 7.0.0
NuGet\Install-Package Nethereum.WebAuthn.Windows -Version 7.0.0
<PackageReference Include="Nethereum.WebAuthn.Windows" Version="7.0.0" />
<PackageVersion Include="Nethereum.WebAuthn.Windows" Version="7.0.0" />
<PackageReference Include="Nethereum.WebAuthn.Windows" />
paket add Nethereum.WebAuthn.Windows --version 7.0.0
#r "nuget: Nethereum.WebAuthn.Windows, 7.0.0"
#:package Nethereum.WebAuthn.Windows@7.0.0
#addin nuget:?package=Nethereum.WebAuthn.Windows&version=7.0.0
#tool nuget:?package=Nethereum.WebAuthn.Windows&version=7.0.0
Nethereum.WebAuthn.Windows
Nethereum.WebAuthn.Windows implements Nethereum.WebAuthn's
IWebAuthnAuthenticator / IWebAuthnCredentialFactory over the Win32 webauthn.dll API, so a
desktop app (Avalonia, WPF, WinUI) gets a real, OS-native Windows Hello passkey - no browser
required.
Requirements
- Windows 10 version 1809 or later (
webauthn.dllships in-box since then). - A registered Windows Hello sign-in (PIN, fingerprint, face). Only the platform authenticator is used; roaming security keys are not supported.
Installation
dotnet add package Nethereum.WebAuthn.Windows
Registering the authenticator
// composition root
services.AddNethereumWebAuthnWindows();
public static IServiceCollection AddNethereumWebAuthnWindows(
this IServiceCollection services,
bool requireUserVerificationForAssertion = true,
bool fallbackToSoftwareOffWindows = true)
On Windows 10 1809+, this registers a singleton WindowsWebAuthnAuthenticator under both
IWebAuthnAuthenticator and IWebAuthnCredentialFactory. Off Windows (macOS/Linux dev machines,
Linux CI), the same two interfaces resolve to Nethereum.WebAuthn's SoftwareWebAuthnAuthenticator
by default - a real P-256 key held in process memory, useful for running the same app/tests
cross-platform, but not a real passkey ceremony: no OS credential store, no biometric prompt, no
hardware-backed key. Pass fallbackToSoftwareOffWindows: false to instead throw
PlatformNotSupportedException on first resolve off Windows.
This cross-platform-TFM + software-fallback design is what lets a shared app project (an Avalonia
view model, for instance) depend on IWebAuthnAuthenticator / IWebAuthnCredentialFactory without
#if WINDOWS conditionals, and still run its tests on any OS.
Usage
using System.Threading.Tasks;
using Nethereum.WebAuthn;
public class PasskeyService
{
private readonly IWebAuthnCredentialFactory _credentialFactory;
private readonly IWebAuthnAuthenticator _authenticator;
public PasskeyService(IWebAuthnCredentialFactory credentialFactory, IWebAuthnAuthenticator authenticator)
{
_credentialFactory = credentialFactory;
_authenticator = authenticator;
}
public async Task<WebAuthnAccountSigningService> RegisterAsync()
{
var created = await _credentialFactory.CreateCredentialAsync(new WebAuthnCredentialCreationOptions
{
RpId = "nethereum.local",
RpName = "My Nethereum App",
UserName = "alice",
RequireUserVerification = true
});
// credentialId is the ON-CHAIN id (keccak of the public key); platformCredentialId is
// Windows Hello's own credential handle used to select the passkey for the assertion - see
// Nethereum.WebAuthn's two-id model.
return new WebAuthnAccountSigningService(
_authenticator, created.OnChainCredentialId, rpId: "nethereum.local",
platformCredentialId: created.PlatformCredentialId);
}
}
This is the desktop-backed half of a passkey account. For the ERC-7579 validator module, the account
init data, and the full create + send flow through IAAClient, see
Nethereum.AccountAbstraction.WebAuthn's Quick
Start - it uses SoftwareWebAuthnAuthenticator for a runnable example, and swapping it for the
WindowsWebAuthnAuthenticator registered here is a one-line change; nothing else in that flow
differs.
Supplying the prompt's parent window: IWindowHandleProvider
public interface IWindowHandleProvider
{
IntPtr GetWindowHandle();
}
AddNethereumWebAuthnWindows parents the Windows Hello UI to the current foreground window by
default (ForegroundWindowHandleProvider). To parent it to your app's own window instead, implement
IWindowHandleProvider and construct WindowsWebAuthnAuthenticator directly:
public class MainWindowHandleProvider : IWindowHandleProvider
{
private readonly IntPtr _mainWindowHandle;
public MainWindowHandleProvider(IntPtr mainWindowHandle)
{
_mainWindowHandle = mainWindowHandle;
}
public IntPtr GetWindowHandle() => _mainWindowHandle;
}
services.AddSingleton(sp => new WindowsWebAuthnAuthenticator(sp.GetRequiredService<MainWindowHandleProvider>()));
Native buffer mapping: WebAuthnNativeBufferMapping
public static class WebAuthnNativeBufferMapping
{
public static string OriginFor(string rpId);
public static string BuildCreateClientDataJson(byte[] challenge, string origin);
public static string BuildGetClientDataJson(byte[] challenge, string origin);
public static WebAuthnCreatedCredential MapCreatedCredential(byte[] authenticatorData, byte[] credentialId, bool requireUserVerification);
public static WebAuthnAssertion MapAssertion(byte[] credentialId, byte[] authenticatorData, string clientDataJson, byte[] derSignature);
}
WindowsWebAuthnAuthenticator calls into this static class rather than building clientDataJSON or
mapping native buffers itself: BuildCreateClientDataJson/BuildGetClientDataJson build the
clientDataJSON string (delegating to Nethereum.WebAuthn.WebAuthnClientData), and
MapCreatedCredential/MapAssertion turn the native webauthn.dll output buffers into
WebAuthnCreatedCredential/WebAuthnAssertion (delegating signature/COSE-key decoding to
Nethereum.WebAuthn.WebAuthnResponseParser). OriginFor(rpId) derives "https://" + rpId as the
origin for the clientDataJSON this package constructs itself, since webauthn.dll has no notion of a
browser origin.
WebAuthnNativeException
public class WebAuthnNativeException : Exception
{
public WebAuthnNativeException(string message, int hresult);
}
Thrown when a webauthn.dll call returns a failing HRESULT; the HRESULT is carried in the
exception's HResult property.
Notes
- All parsing (DER signatures, COSE public keys, authenticatorData) is delegated to
Nethereum.WebAuthn.WebAuthnResponseParser- this package only owns the nativewebauthn.dllcall and the unmanaged buffer marshaling around it (seeNativeWebAuthn.cs, which mirrors the Windows SDK'swebauthn.hstruct layouts). - The live Windows Hello prompt (an actual OS UI, requiring an enrolled biometric/PIN) cannot run in a
headless test suite; it is exercised manually in the Avalonia AA demo. The unit tests in
tests/Nethereum.WebAuthn.Windows.UnitTestsinstead verify the clientDataJSON construction and the native-buffer-to-WebAuthnAssertion/WebAuthnCreatedCredentialmapping (WebAuthnNativeBufferMapping's publicBuild*ClientDataJson/Map*helpers) against real BCL-generated P-256 keys/signatures, plus the off-Windows software fallback registration. WindowsWebAuthnAuthenticatoronly ever requests the platform authenticator (Windows Hello itself), never a cross-platform/security-key one.
Related Packages
- Nethereum.WebAuthn - the platform-agnostic seams, the two-id model,
SoftwareWebAuthnAuthenticator - Nethereum.AccountAbstraction.WebAuthn - the ERC-7579 validator module + end-to-end account create/send flow
- Nethereum.WebAuthn.Blazor - the browser equivalent of this package
Additional Resources
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Nethereum.WebAuthn (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Nethereum.WebAuthn (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Nethereum.WebAuthn (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 7.0.0 | 101 | 10/2/2026 |