Tako0502.EgovHelper 0.1.0

dotnet add package Tako0502.EgovHelper --version 0.1.0
                    
NuGet\Install-Package Tako0502.EgovHelper -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tako0502.EgovHelper" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tako0502.EgovHelper" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Tako0502.EgovHelper" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tako0502.EgovHelper --version 0.1.0
                    
#r "nuget: Tako0502.EgovHelper, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tako0502.EgovHelper@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tako0502.EgovHelper&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Tako0502.EgovHelper&version=0.1.0
                    
Install as a Cake Tool

Tako0502.EgovHelper

Backend companion for @smoker_winston/egov-helper.

Verifies CMS / CAdES-BES signatures produced by Kazakhstan e-Gov certificates (NUC RK / pki.gov.kz) and extracts BIN/IIN/owner info from the signing certificate. No NCALayer required on the server side — pure .NET, uses System.Security.Cryptography.Pkcs.SignedCms.

Install

dotnet add package Tako0502.EgovHelper

Targets netstandard2.1 and net8.0.

Usage

Verify a signature posted from your frontend

The browser uses @smoker_winston/egov-helper to sign a contract and POSTs you the base64 signature (and, for detached signatures, the original document):

using Tako0502.EgovHelper;
using System.Security.Cryptography.X509Certificates;

[HttpPost("/api/contracts/sign")]
public IActionResult Sign([FromBody] SignRequest req)
{
    var signature = Convert.FromBase64String(req.SignatureBase64);
    var document = Encoding.UTF8.GetBytes(req.ContractText);

    // Load NUC RK roots once at app startup, not on every request.
    var roots = new[]
    {
        new X509Certificate2("certs/root_rsa.cer"),
        new X509Certificate2("certs/nca_rsa.cer"),
    };

    var result = EgovSignatureVerifier.Verify(signature, document, new VerifyOptions
    {
        ValidateCertificateChain = true,
        TrustedRoots = roots,
        IgnoreOfflineRevocation = false,
    });

    if (!result.Valid)
    {
        return BadRequest(new
        {
            error = result.ErrorMessage ?? result.Signers.FirstOrDefault()?.SignatureError,
        });
    }

    var signer = result.Signers[0];

    // The whole point of this library: prove that whoever signed the contract really
    // owns this BIN/IIN, not just that they typed it in your form.
    if (signer.CertInfo.Bin != req.ExpectedBin)
    {
        return Forbid("Signing cert BIN does not match the user's claimed BIN");
    }

    return Ok(new
    {
        signer = signer.CertInfo.CommonName,
        bin = signer.CertInfo.Bin,
        iin = signer.CertInfo.Iin,
        signedAt = signer.SignedAt,
        cadesBes = signer.HasSigningCertificateV2,
        timestamped = signer.HasTimestamp,
    });
}

Just decode (no verification — for showing "who signed this")

var result = EgovSignatureVerifier.Inspect(signatureBytes);
foreach (var s in result.Signers)
{
    Console.WriteLine($"Signed by {s.CertInfo.CommonName} (BIN: {s.CertInfo.Bin}) at {s.SignedAt}");
}

Extract BIN/IIN from a certificate you already have

var cert = new X509Certificate2("user.cer");
var info = BinExtractor.Extract(cert);
Console.WriteLine($"BIN: {info.Bin}, IIN: {info.Iin}");

Trust setup — getting NUC RK roots

SignedCms.CheckSignature(verifySignatureOnly: false) only validates against trust roots installed on the OS, which on Windows / Linux / macOS does not include NUC RK by default. You have two options:

  1. Pass roots explicitly (recommended): download from https://pki.gov.kz/ and pass via VerifyOptions.TrustedRoots. On .NET 5+ this uses X509ChainTrustMode.CustomRootTrust, so the OS store is bypassed entirely. On netstandard2.1 the roots go into ExtraStore and you need them installed in the OS trust store too.
  2. Skip chain validation (ValidateCertificateChain = false): only checks that the signature value verifies against the embedded cert. Acceptable if you trust the cert by other means (e.g. you imported it from a recent successful login).

What's verified

Check Inspect() Verify(opts.ValidateCertificateChain=false) Verify(opts.ValidateCertificateChain=true)
CMS parses ✅ ✅ ✅
Signed attributes extracted ✅ ✅ ✅
Cert chain built – – ✅
Signer's RSA signature checks against cert – ✅ ✅
Cert revocation (CRL/OCSP) – – ✅ (best-effort, see IgnoreOfflineRevocation)
messageDigest matches the document implicit (CheckSignature does this when document is provided) ✅ ✅
Timestamp token (CAdES-T) authenticity flagged but not verified flagged but not verified flagged but not verified

License

MIT

Product 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 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 netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
0.1.0 347 5/9/2026