SmartId 3.2.0
dotnet add package SmartId --version 3.2.0
NuGet\Install-Package SmartId -Version 3.2.0
<PackageReference Include="SmartId" Version="3.2.0" />
<PackageVersion Include="SmartId" Version="3.2.0" />
<PackageReference Include="SmartId" />
paket add SmartId --version 3.2.0
#r "nuget: SmartId, 3.2.0"
#:package SmartId@3.2.0
#addin nuget:?package=SmartId&version=3.2.0
#tool nuget:?package=SmartId&version=3.2.0
<div align="center"> <img src="assets/nuget/package-icon.png" alt="Smart-ID" width="64" height="64"> </div>
Smart-ID .NET client
.NET Standard 2.0 client for Smart-ID RP API v3 (device-link and notification flows). Ported from the official smart-id-java-client; public surface and behaviour follow the Java library where applicable.
Official protocol documentation: Smart-ID RP API.
Table of contents
- Introduction
- Features
- Requirements
- Getting the library
- How to use (API v3)
- Testing this repository
- License
Introduction
Use this library to integrate Smart-ID authentication, qualified signing, and certificate discovery into .NET applications. All session initiation and status calls are asynchronous (async / Task).
Features
- User authentication (device-link and notification)
- Digital signature sessions (device-link and notification)
- Device-link certificate choice and linked notification signature flow
- Query end-user signing certificate by document number
- Device-link URI construction (
DeviceLinkBuilder) withauthCode - Session status polling and response validation (PKIX-style trust for user certificates)
Requirements
- .NET implementing .NET Standard 2.0 (e.g. .NET Framework 4.6.1+, .NET Core 2.0+, modern .NET)
- Runtime dependencies (pulled in with the package): BouncyCastle.Cryptography, System.Text.Json
Getting the library
Add a project reference to src/SmartId/SmartId.csproj (or pack the project and reference the resulting NuGet).
<ItemGroup>
<ProjectReference Include="path\to\SmartId.csproj" />
</ItemGroup>
Main namespace: SK.SmartId. REST connector types: SK.SmartId.Rest. DTOs: SK.SmartId.Rest.Dao.
How to use (API v3)
Import types from SK.SmartId and SK.SmartId.Rest as needed. The entry point is SmartIdClient, which exposes factory methods for request builders (e.g. CreateDeviceLinkAuthentication(), CreateNotificationSignature()) and CreateDynamicContent() for DeviceLinkBuilder.
Test accounts for testing
Use Smart-ID demo accounts, semantics identifiers, and document numbers from SK documentation:
Test accounts.
Public demo RP (used in examples below, integration tests, and the official Java README):
| Setting | Value |
|---|---|
| Relying party UUID | 00000000-0000-4000-8000-000000000000 |
| Relying party name | DEMO |
| API base URL | https://sid.demo.sk.ee/smart-id-rp/v3/ |
| Device-link scheme (demo) | smart-id-demo (instead of default smart-id) |
Use your own registered RP UUID and name in production. Smart-ID Basic (ADVANCED) accounts are not supported on DEMO — see SK environment docs.
Logging HTTP traffic
There is no global logging switch. To log requests and responses (similar in spirit to the Java client’s Jersey filter), build an HttpClient whose handler chain includes SmartIdHttpLoggingHandler (SK.SmartId.Rest), then pass that client to SmartIdClient.SetConfiguredClient(HttpClient).
Assign LogDebug / LogTrace delegates to write method + URI, status lines, and optional bodies.
Configuring SmartIdClient
var httpClient = new HttpClient { Timeout = TimeSpan.FromMinutes(2) };
// Optional: wrap handler with SmartIdHttpLoggingHandler for diagnostics.
var client = new SmartIdClient();
client.SetRelyingPartyUUID("00000000-0000-4000-8000-000000000000");
client.SetRelyingPartyName("DEMO");
client.SetHostUrl("https://sid.demo.sk.ee/smart-id-rp/v3/");
client.SetConfiguredClient(httpClient);
Optional:
SetPollingSleepTimeout(TimeSpan)— delay between session status polls (default 1 second).SetSessionStatusResponseSocketOpenTime(TimeSpan?)— forwarded to the REST connector for long-poll styletimeoutMson session status GET (when supported by your connector implementation).
You can replace the connector entirely with SmartIdClient.SmartIdConnector = myConnector if you implement ISmartIdConnector.
TLS to Smart-ID
Unlike the Java client’s setTrustStore(JKS), this library does not ship a JKS loader. Configure TLS the usual .NET way:
- Use the default
HttpClientHandlercertificate validation (OS trust store), or - Provide a custom
HttpClientHandler/SocketsHttpHandlerwithServerCertificateCustomValidationCallbackor client certificates as required by your environment.
Pin or load SK demo/production TLS certificates per Smart-ID HTTPS documentation.
Certificate chain validation for session responses (user TLS auth certs) is separate: use CertificateValidatorImpl with embedded PEM trust material (CertificateValidatorImpl.CreateDefault()) or construct it with your own anchor/intermediate X509Certificate2 list. This mirrors validating the authentication/signing certificate from SessionStatus, not the TLS channel.
Device-link flows
Device-link sessions are started via SmartIdClient.CreateDeviceLinkAuthentication(), CreateDeviceLinkSignature(), or CreateDeviceLinkCertificateRequest(). Typical pattern:
- Configure the builder (
WithRpChallenge,WithSemanticsIdentifierorWithDocumentNumber,WithInteractions, etc.). - Call
InitAsync(CancellationToken)on the builder to obtainDeviceLinkSessionResponse. - Persist
GetAuthenticationSessionRequest()(or the equivalent request object) for later validation. - Build the user-facing link with
client.CreateDynamicContent()→DeviceLinkBuilder: set scheme (e.g.smart-id-demofor demo),WithDeviceLinkBase,WithDeviceLinkType,WithSessionType,WithSessionToken,WithDigest,WithLang,WithElapsedSeconds(required for QR),WithInteractionswhere applicable, thenBuildDeviceLink(sessionSecret).
Parameter semantics match the Java client and device link flows.
QR codes (third-party libraries)
The Java client includes a helper that builds QR images (ZXing). This .NET library does not ship QR encoding: adding it would drag in heavy optional dependencies (image stacks, barcode bindings, security surface) for every consumer, while many backends only forward the device-link string to a SPA or mobile app that already renders QR.
Use a third-party library where you need a bitmap or data URI, for example QRCoder, ZXing.Net, or platform APIs. Encode the full device-link URI returned from DeviceLinkBuilder.BuildDeviceLink(sessionSecret) (same string you would pass to the Java QrCodeGenerator).
Notification-based flows
Use CreateNotificationAuthentication(), CreateNotificationSignature(), or CreateNotificationCertificateChoice(). Call InitAsync on the corresponding builder to start a session; poll session status the same way as for device-link flows.
Linked notification signature
After a device-link certificate choice session completes, you can start a CreateLinkedNotificationSignature() session with WithLinkedSessionID, WithDocumentNumber, digest input (SignableData / SignableHash), algorithm, and interactions. Initiate with InitAsync.
Certificate by document number
var certResult = await client.CreateCertificateByDocumentNumber()
.WithDocumentNumber("PNOEE-…")
.GetCertificateByDocumentNumberAsync();
Session status
- One-shot:
await client.SmartIdConnector.GetSessionStatusAsync(sessionId, cancellationToken) - Poll until
StateisCOMPLETE:await client.GetSessionStatusPoller().FetchFinalSessionStatusAsync(sessionId, cancellationToken)
Validating session results
Use the typed validators (same roles as in the Java client), for example:
DeviceLinkAuthenticationResponseValidator— device-link authentication; useDefaultSetupWithCertificateValidator(ICertificateValidator)or inject dependencies as in the JavadefaultSetupWithCertificateValidator.NotificationAuthenticationResponseValidatorCertificateChoiceResponseValidatorSignatureResponseValidator
Pass SessionStatus, the original session request DTO, challenge/certificate level as required by the flow. CertificateValidatorImpl.CreateDefault() supplies SK test/production CA material bundled as PEM resources for PKIX-style trust (BouncyCastle path building).
Callback URL helpers
For Web2App / App2App flows, SK.SmartId.Util.CallbackUrlUtil provides CreateCallbackUrl, ValidateSessionSecretDigest, and related helpers aligned with the Java client.
Exceptions
Typed errors live under SK.SmartId.Exceptions, SK.SmartId.Exceptions.Permanent, SK.SmartId.Exceptions.UserActions, SK.SmartId.Exceptions.UserAccounts, following the Java exception mapping (e.g. user refused, timeout, document unusable).
Testing this repository
dotnet test smart-id-net-client.sln --filter "Category!=DemoIntegrationReadme"
Integration tests tagged DemoIntegrationReadme (live demo + mock device-link) are excluded from the default command above; see .github/workflows/dotnet.yml. Java ↔ .NET test mapping: docs/java-unit-test-parity.md.
License
See LICENSE. The library is published under the MIT License, matching the upstream smart-id-java-client license; copyright notices for both the original work (SK ID Solutions AS) and this port are in LICENSE.
The Smart-ID graphic in this README and in the NuGet package is taken from the official Smart-ID documentation (Smart-ID login assets; stated there as free to use). It is resized for NuGet; Smart-ID is a trademark of its owner. This project is not affiliated with SK ID Solutions.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 was computed. 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 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- BouncyCastle.Cryptography (>= 2.6.2)
- System.Text.Json (>= 10.0.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.