EImzo.Client
1.1.0
dotnet add package EImzo.Client --version 1.1.0
NuGet\Install-Package EImzo.Client -Version 1.1.0
<PackageReference Include="EImzo.Client" Version="1.1.0" />
<PackageVersion Include="EImzo.Client" Version="1.1.0" />
<PackageReference Include="EImzo.Client" />
paket add EImzo.Client --version 1.1.0
#r "nuget: EImzo.Client, 1.1.0"
#:package EImzo.Client@1.1.0
#addin nuget:?package=EImzo.Client&version=1.1.0
#tool nuget:?package=EImzo.Client&version=1.1.0
EImzo.Client - E-IMZO .NET Client SDK
Disclaimer: This library is an unofficial, community-driven client SDK. It is not affiliated with, sponsored by, or endorsed by the State Tax Committee of Uzbekistan (DSQ), SIC "Yangi Texnologiyalar", or official E-IMZO service operators.
High-performance, community-maintained unofficial .NET Client SDK for Uzbekistan's E-IMZO and E-IMZO-SERVER REST-API and Mobile ID-CARD system.
Reference documentation: qo0p/e-imzo-doc.
Compatible Server Image: 0605AbMu/e-imzo-server (ghcr.io/0605abmu/e-imzo-server).
🔄 Server Compatibility Matrix
Client SDK (EImzo.Client) |
Compatible E-IMZO Server | Docker Image Reference | Status |
|---|---|---|---|
1.x.x |
v2.2.1 (and all 2.x REST APIs) |
ghcr.io/0605abmu/e-imzo-server:2.2.1 |
✅ Tested & Supported |
This SDK follows Semantic Versioning 2.0. Patch and minor releases introduce client-side enhancements, performance optimizations, and bug fixes while maintaining full compatibility with the server endpoints.
📦 Installation
Option 1: Via GitHub Packages
- Add the GitHub Packages NuGet source using your Personal Access Token (
read:packagesscope):
dotnet nuget add source --name github \
--username <GITHUB_USERNAME> \
--password <GITHUB_PAT> \
--store-password-in-clear-text \
"https://nuget.pkg.github.com/0605AbMu/index.json"
- Add the package to your project:
dotnet add package EImzo.Client
Alternatively, add nuget.config to your solution root:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="github" value="https://nuget.pkg.github.com/0605AbMu/index.json" />
</packageSources>
<packageSourceCredentials>
<github>
<add key="Username" value="%GITHUB_USERNAME%" />
<add key="ClearTextPassword" value="%GITHUB_TOKEN%" />
</github>
</packageSourceCredentials>
</configuration>
Option 2: Via NuGet.org (once published)
dotnet add package EImzo.Client
Or via Package Manager Console:
Install-Package EImzo.Client
⚡ Key Highlights
- Multi-Target Support:
.NET 8.0,.NET 9.0,.NET Standard 2.0, and.NET Standard 2.1(cross-platform, compatible with ASP.NET Core, .NET Core, .NET Framework 4.6.1+, Blazor, and MAUI). - Native Dependency Injection: Seamlessly integrates with
Microsoft.Extensions.DependencyInjectionandIHttpClientFactory. - Complete Endpoint Coverage:
- Health & Info:
/ping,/info - Web Auth & Verification:
/frontend/challenge,/backend/auth,/backend/pkcs7/verify/attached,/backend/pkcs7/verify/detached,/frontend/timestamp/pkcs7,/frontend/pkcs7/make-attached,/frontend/pkcs7/join - E-IMZO Mobile ID-CARD:
/frontend/mobile/auth,/frontend/mobile/sign,/frontend/mobile/status,/frontend/mobile/upload,/backend/mobile/authenticate/{DocumentID},/backend/mobile/verify
- Health & Info:
- Smart Subject Certificate Mapping:
Pinfl(JSHSHIR - 14 digits) from OID1.2.860.3.16.1.2LegalEntityTin(STIR - 9 digits) from OID1.2.860.3.16.1.1PhysicalPersonTinfromUIDCommonName(CN),FirstName,Surname,Organization,IsLegalEntity,IsPhysicalPerson
- Key Type Detection: Auto-detects key/token type via
paramSetOID(Pfx,IdCard,Baik,Uzguard). - Mobile QR & Deeplink Generator: Built-in IEEE 802.3 CRC32 calculation and standard
eimzo://sign?qc=...generation. - Multi-Language Error Descriptions: Human-readable descriptions for all E-IMZO status codes in Uzbek (
uz), Russian (ru), and English (en).
🚀 Quick Start
1. Registering with Dependency Injection (ASP.NET Core / Worker Service)
In Program.cs:
using EImzo.Client;
var builder = WebApplication.CreateBuilder(args);
// Register E-IMZO Client
builder.Services.AddEImzoClient(options =>
{
options.BaseUrl = new Uri(builder.Configuration["EImzo:BaseUrl"] ?? "http://127.0.0.1:8080/");
options.DefaultHost = "myportal.uz"; // Sent in HTTP 'Host' header
options.DefaultRealIp = "127.0.0.1"; // Sent in HTTP 'X-Real-IP' header
options.Timeout = TimeSpan.FromSeconds(30);
options.ThrowOnError = false; // If true, auto-throws EImzoApiException when Status != 1
});
Inject IEImzoClient into your services or controllers:
public class AuthService
{
private readonly IEImzoClient _eimzoClient;
public AuthService(IEImzoClient eimzoClient)
{
_eimzoClient = eimzoClient;
}
}
2. Standalone Client (Without Dependency Injection)
using EImzo.Client;
var options = new EImzoClientOptions
{
BaseUrl = new Uri("http://127.0.0.1:8080/"),
DefaultHost = "myportal.uz"
};
using var httpClient = new HttpClient();
IEImzoClient client = new EImzoClient(httpClient, options);
📖 Usage Examples
A. Web Authentication Flow (Challenge & Auth)
Step 1: Generate Challenge for Frontend
var challengeResponse = await client.GetChallengeAsync();
if (challengeResponse.IsSuccess)
{
string challenge = challengeResponse.Challenge!; // Send to frontend for E-IMZO sign
int ttlSeconds = challengeResponse.Ttl; // e.g. 120s
}
Step 2: Authenticate User on Backend
Frontend returns PKCS#7 signature in Base64:
var authResponse = await client.AuthenticateAsync(pkcs7Base64, realIp: userIp, host: "myportal.uz");
if (authResponse.IsSuccess)
{
var cert = authResponse.SubjectCertificateInfo!;
string pinfl = cert.Pinfl!; // 14-digit JSHSHIR
string tin = cert.Tin!; // STIR (Company or Personal)
string fullName = cert.CommonName!; // Full name
bool isCompany = cert.IsLegalEntity; // True if legal entity
// Login user into your application session...
}
else
{
// Inspect localized error explanation
string errorUz = authResponse.StatusCode.GetDescription("uz");
string errorEn = authResponse.StatusCode.GetDescription("en");
Console.WriteLine($"Auth failed: {errorUz} (Code: {authResponse.Status})");
}
B. PKCS#7 Document Verification
Attached Verification (Includes document + timestamp)
var verifyResponse = await client.VerifyAttachedAsync(pkcs7AttachedBase64, realIp: userIp);
if (verifyResponse.IsSuccess)
{
string signedDocBase64 = verifyResponse.Pkcs7Info!.DocumentBase64!;
bool allValid = verifyResponse.Pkcs7Info.IsAllSignersValid;
foreach (var signer in verifyResponse.Pkcs7Info.Signers!)
{
Console.WriteLine($"Signed by: {signer.UserCertificate?.SubjectName}");
Console.WriteLine($"Signing Time: {signer.SigningTime}");
Console.WriteLine($"Signature Valid: {signer.Verified}");
Console.WriteLine($"Cert Valid: {signer.CertificateVerified}");
}
}
Detached Verification
var verifyResponse = await client.VerifyDetachedAsync(documentBase64, pkcs7DetachedBase64);
Attaching Timestamp Token
var timestampResponse = await client.AttachTimestampAsync(pkcs7Base64);
string pkcs7WithTimestamp = timestampResponse.Pkcs7Base64!;
Multi-Signature Joining (Section 2.2.8)
// Combine two independently signed Attached PKCS#7 containers
var joinResponse = await client.JoinAttachedAsync(containerA, containerB);
string mergedContainer = joinResponse.Pkcs7Base64!;
C. E-IMZO Mobile ID-CARD Flow
1. Initiate Mobile Authentication
var mobileAuth = await client.MobileAuthAsync();
string siteId = mobileAuth.SiteId!;
string documentId = mobileAuth.DocumentId!;
string challenge = mobileAuth.Challenge!;
// Compute digest of challenge (e.g. O'zDSt 1106 / GOST hash in hex)
string hexHash = ComputeGostHashHex(challenge);
// Generate QR Code payload (siteId + documentId + hexHash + CRC32)
string qrPayload = EImzoMobileHelper.BuildQrCode(siteId, documentId, hexHash);
// Generate Deeplink for mobile app (eimzo://sign?qc=...)
string deepLink = EImzoMobileHelper.BuildDeepLink(qrPayload);
2. Poll Status
var statusResponse = await client.GetMobileStatusAsync(documentId);
if (statusResponse.IsCompleted)
{
// Status == 1: Mobile user finished signing and uploaded PKCS#7
}
else if (statusResponse.IsPending)
{
// Status == 2: Waiting for user action in mobile app
}
3. Backend Verification
// For mobile auth:
var authResult = await client.MobileAuthenticateAsync(documentId);
string pinfl = authResult.SubjectCertificateInfo?.Pinfl;
// For mobile document sign:
var signResult = await client.MobileVerifyAsync(documentId, documentBytes);
🛡 Status Code Reference
| Code | Enum | Description (UZ) | Description (RU) |
|---|---|---|---|
1 |
Success |
Muvaffaqiyatli | Успешно |
-1 |
VpnOrCertificateCheckFailed |
Sertifikat holatini tekshirib bo'lmadi (VPN uzilgan) | Не удалось проверить статус сертификата (VPN) |
-5 |
TimestampWindowExceeded |
Imzolash vaqti ruxsat etilgan oraliqdan tashqarida | Время подписи вне допустимого окна |
-10 |
SignatureInvalid |
ERI (PKCS#7) imzosi haqiqiy emas | ЭЦП недействительна |
-11 |
CertificateInvalid |
Sertifikat haqiqiy emas | Сертификат недействителен |
-12 |
CertificateInvalidAtSigningTime |
Sertifikat imzolash paytida haqiqiy bo'lmagan | Сертификат недействителен на дату подписи |
-20 |
ChallengeNotFoundOrExpired |
Challenge topilmadi yoki muddati tugagan | Не найден challenge или срок его истек |
-24 |
CertificatePolicyDisallowed |
Sertifikat siyosati ruxsat etilmagan | Политика сертификата не входит в разрешённый набор |
-25 |
CaCertificateDisallowed |
CA sertifikati ruxsat etilmagan | Сертификат УЦ не разрешён для проверки |
📄 License
This SDK is distributed under the MIT License.
| 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 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 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 is compatible. |
| .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
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- System.Text.Json (>= 8.0.5)
-
.NETStandard 2.1
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- System.Text.Json (>= 8.0.5)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- System.Text.Json (>= 8.0.5)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- System.Text.Json (>= 8.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.