Tako0502.EgovHelper
0.1.0
dotnet add package Tako0502.EgovHelper --version 0.1.0
NuGet\Install-Package Tako0502.EgovHelper -Version 0.1.0
<PackageReference Include="Tako0502.EgovHelper" Version="0.1.0" />
<PackageVersion Include="Tako0502.EgovHelper" Version="0.1.0" />
<PackageReference Include="Tako0502.EgovHelper" />
paket add Tako0502.EgovHelper --version 0.1.0
#r "nuget: Tako0502.EgovHelper, 0.1.0"
#:package Tako0502.EgovHelper@0.1.0
#addin nuget:?package=Tako0502.EgovHelper&version=0.1.0
#tool nuget:?package=Tako0502.EgovHelper&version=0.1.0
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:
- Pass roots explicitly (recommended): download from https://pki.gov.kz/ and pass via
VerifyOptions.TrustedRoots. On .NET 5+ this usesX509ChainTrustMode.CustomRootTrust, so the OS store is bypassed entirely. On netstandard2.1 the roots go intoExtraStoreand you need them installed in the OS trust store too. - 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 | 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 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. |
-
.NETStandard 2.1
- System.Security.Cryptography.Pkcs (>= 8.0.0)
-
net8.0
- System.Security.Cryptography.Pkcs (>= 8.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 |
|---|---|---|
| 0.1.0 | 347 | 5/9/2026 |