Viwo.Signer is an independent .NET-based XML signing and verification library focused on XAdES-BES / XAdES-T signatures for Turkish e-document scenarios such as e-Defter, berat, e-Fatura, e-İrsaliye and other XML-based documents.
The project supports signing with AKİS / PKCS#11 smart cards, optional PFX fallback for development/testing, KamuSM RFC3161 timestamp integration, TÜBİTAK/KamuSM timestamp identity header, local certificate store validation, CRL/SİL revocation checks, and ESYA-like detailed verification reports.
This project is not affiliated with TÜBİTAK, KamuSM, GİB, or ESYA.
It is an independent implementation and must be validated carefully before production use.
- XML Digital Signature support
- XAdES-BES support
- XAdES-T support with RFC3161 timestamp
- Enveloped XML signature
- Inclusive canonicalization support
SignedPropertiesreference supportSigningTimeSigningCertificateDataObjectFormatSignerRole / ClaimedRole- RSA and ECDSA signing support
- AKİS / PKCS#11 signing provider
- PFX fallback signing provider for development and test scenarios
- RFC3161 timestamp request generation
- KamuSM test and production timestamp endpoints
- TÜBİTAK/KamuSM custom
identityheader support - PBKDF2-HMAC-SHA256 based identity generation
- AES-256-CBC encrypted timestamp authentication payload
- ASN.1 DER encoded identity token
- Hex encoded HTTP
identityheader - KamuSM timestamp credit query support
- Timestamp token verification
- Timestamp
MessageImprintverification - TSA certificate validation
- TSA CRL/SİL validation
- Signature value verification
- RSA / ECDSA verification
- Reference digest verification
URI=""document reference verificationSignedPropertiesdigest verificationSigningCertificatedigest verificationSigningTimevalidationDataObjectFormatvalidationSignatureTimeStampvalidationEncapsulatedTimeStampvalidation- Timestamp token mathematical verification
- Timestamp content digest verification
- Signer certificate chain validation
- Timestamp TSA certificate chain validation
- Local custom trust store support
- Windows certificate store independent validation
- Local CRL/SİL revocation checks
- ESYA-like detailed verification report
- KamuSM certificate manifest support
- Automatic download of required certificates
- Local certificate store under
certs/kamusm - Root certificates
- Intermediate certificates
- Timestamp certificates
- CRL/SİL files
- Test certificates
- KamuSM
SertifikaDeposu.xmlcache support - Optional repository-based certificate loading
- Local custom trust validation
- Dummy test root CA for PFX fallback signatures
Viwo.Signer currently focuses on XML/XAdES signatures.
Supported:
- XAdES-BES
- XAdES-T
- XML signature verification
- KamuSM timestamp
- KamuSM timestamp credit query
- AKİS / PKCS#11 smart card signing
- PFX fallback signing
- Local certificate and CRL validation
Not currently supported:
- CAdES
- PAdES / PDF signing
- ASiC containers
- Mobile signature
- HSM-specific integration
- ES-C / ES-X / ES-XL / ES-A long-term archive signature profiles
- OCSP / ÇiSDuP online revocation validation
- Full ESYA policy engine compatibility
- .NET 10.0 or later
- Windows recommended for AKİS / smart card usage
- AKİS middleware / PKCS#11 driver for real mali mühür signing
- Internet connection for certificate and timestamp operations
- KamuSM timestamp account for production timestamp usage
Example structure:
Viwo.Signer
├── Viwo.Signer
│ ├── Xml
│ ├── Timestamping
│ ├── Certificates
│ └── Signing
│
├── Viwo.Signer.Test
│ ├── Data
│ ├── certs
│ │ └── kamusm
│ │ └── kamusm-certificates.xml
│ └── Program.cs
│
└── README.md
The KamuSM certificate manifest is located at:
certs/kamusm/kamusm-certificates.xml
This manifest defines all certificates and CRL/SİL files required for local validation.
Example entries:
<File
id="mmeshs-s3"
name="Mali Mühür Elektronik Sertifika Hizmet Sağlayıcısı - Sürüm 3"
type="Intermediate"
environment="Production"
url="http://depo.kamusm.gov.tr/kurumsal/mmeshs-s3.crt"
path="intermediates/mmeshs-s3.crt"
required="true"
enabled="true" />
<File
id="kamusm-root-s7"
name="Kamu SM Kök Sertifika Hizmet Sağlayıcısı - Sürüm 7"
type="Root"
environment="Production"
url="https://sertifikalar.kamusm.gov.tr/nes/KOKSHS.V7.crt"
path="roots/kamusm-kok-s7.crt"
required="true"
enabled="true" />
<File
id="kamusm-root-s7-crl"
name="Kamu SM Kök Sertifika Hizmet Sağlayıcısı - Sürüm 7 CRL"
type="Crl"
environment="Production"
url="https://sertifikalar.kamusm.gov.tr/nes/kokshs.v7.crl"
path="crl/kamusm-kok-s7.crl"
required="false"
enabled="true" />Downloaded certificates are stored locally under:
certs/kamusm
├── roots
├── intermediates
├── timestamp
├── crl
├── repository
├── test
└── local-test
Do not commit generated certificates, PFX files, private keys, live appsettings or real signed XML documents.
Recommended .gitignore additions:
# App Settings - local/secrets
appsettings.*.json
!appsettings.json
!appsettings.example.json
# Certificate/private key materials
*.pfx
*.p12
*.p7b
*.key
*.pem
*.snk
*.license
lisans.xml
# Generated signed/tampered XML files
signed/
*-signed.xml
*-tampered.xml
*.verify-report.json
*.verify-report.xml
# Downloaded KamuSM certificates / CRL / repository cache
certs/**
**/certs/**
# Keep only KamuSM manifest files
!certs/
!certs/kamusm/
!certs/kamusm/kamusm-certificates.xml
!**/certs/
!**/certs/kamusm/
!**/certs/kamusm/kamusm-certificates.xml
# Private test data
**/Data/Private/
**/Data/Signed/
**/Data/Production/Example appsettings.json:
{
"Signer": {
"Timestamp": {
"Enabled": true,
"ServerUrl": "http://tzd.kamusm.org.tr",
"UseTubitakIdentityHeader": true,
"CustomerNo": "21",
"CustomerPassword": "12345678",
"PolicyOid": "2.16.792.1.2.1.1.5.7.3.1",
"HashAlgorithm": "Sha256"
},
"Verify": {
"VerifyCertificateChain": true,
"CheckCertificateRevocation": false,
"VerifyTimestamp": true,
"RequireTimestamp": true,
"VerifyTimestampCertificateChain": true,
"CheckTimestampRevocation": false,
"UseTimestampAsValidationTime": true,
"TreatUntrustedRootAsWarning": false,
"UseLocalKamuSmCertificateStore": true,
"LocalKamuSmCertificateDirectory": "certs\\kamusm",
"UseCustomRootTrustForKamuSm": true,
"UseKamuSmCertificateRepository": false,
"CheckCertificateRevocationWithLocalCrl": true,
"CheckTimestampRevocationWithLocalCrl": true,
"TreatMissingCrlAsWarning": true
},
"KamuSmCertificates": {
"Enabled": true,
"AutoDownload": true,
"BaseDirectory": "certs\\kamusm",
"ManifestPath": "certs\\kamusm\\kamusm-certificates.xml",
"DownloadTimeoutSeconds": 30,
"OverwriteExisting": false
},
"CertificateRepository": {
"Enabled": true,
"AutoDownload": true,
"Url": "http://depo.kamusm.gov.tr/depo/SertifikaDeposu.xml",
"CachePath": "certs\\kamusm\\repository\\SertifikaDeposu.xml",
"DownloadTimeoutSeconds": 30,
"RefreshIfOlderThanHours": 24,
"UseCertificatesAsExtraStore": true,
"TrustRepositoryRoots": false
},
"PfxFallback": {
"Enabled": true,
"AutoCreateDummyCertificate": true,
"AutoInstallDummyRootToCurrentUser": false,
"CertificateDirectory": "certs\\kamusm",
"PfxPath": "certs\\kamusm\\local-test\\signers\\viwo-test-signer-ecdsa.pfx",
"PfxPassword": "Viwo.Test.123!",
"Algorithm": "ECDSA"
}
}
}Do not commit production timestamp credentials, PIN values, PFX passwords or private keys.
{
"ServerUrl": "http://tzd.kamusm.org.tr",
"CustomerNo": "21",
"CustomerPassword": "12345678"
}{
"ServerUrl": "http://zd.kamusm.gov.tr",
"CustomerNo": "YOUR_CUSTOMER_NO",
"CustomerPassword": "YOUR_CUSTOMER_PASSWORD"
}Production credentials must be stored in:
appsettings.Development.json
or another secure configuration source.
KamuSM timestamp integration requires a custom HTTP authentication header in addition to RFC3161.
The identity generation flow is:
1. Create RFC3161 TimeStampReq
2. Calculate the timestamp request imprint/hash
3. Generate authentication token
4. Derive AES key with PBKDF2WithHmacSHA256
5. Encrypt payload using AES-256-CBC
6. Encode structure using ASN.1 DER
7. Convert DER bytes to hexadecimal
8. Send with HTTP header: identity
The request is sent with:
Content-Type: application/timestamp-query
identity: <hex-encoded-token>The test console supports querying remaining KamuSM timestamp credit.
The credit query flow uses:
SHA1(customerId + epochMilliseconds)
and sends the required headers:
identity: <generated identity>
credit_req: <customerId>
credit_req_time: <epochMilliseconds>
User-Agent: UEKAE TSS ClientExample console output:
KamuSM Timestamp Credit
Customer No : 21
Credit : 999999
Server : http://tzd.kamusm.org.tr
Viwo.Signer can validate signatures without relying on Windows Trusted Root Store.
Recommended settings:
{
"UseLocalKamuSmCertificateStore": true,
"LocalKamuSmCertificateDirectory": "certs\\kamusm",
"UseCustomRootTrustForKamuSm": true,
"UseKamuSmCertificateRepository": false
}Expected verification log:
Certificate local KamuSM store loaded. Roots=...
Certificate chain trust source: Local KamuSM CustomTrustStore
Certificate chain root source : LocalRoot
Timestamp TSA local KamuSM store loaded. Roots=...
Timestamp TSA chain trust source: Local KamuSM CustomTrustStore
Timestamp TSA chain root source : LocalRoot
The verifier supports offline CRL/SİL checks using locally downloaded CRL files.
Enabled by:
{
"CheckCertificateRevocationWithLocalCrl": true,
"CheckTimestampRevocationWithLocalCrl": true,
"TreatMissingCrlAsWarning": true
}Example successful CRL output:
Certificate CRL OK.
Subject=CN=BLOG POLİMER ANONİM ŞİRKETİ, SERIALNUMBER=1780716915
CRL=mmeshs-s3.crl
Timestamp TSA CRL OK.
Subject=CN=Kamu SM Zaman Damgasi Sunucusu S1, O=TUBITAK, C=TR
CRL=kamusm-kok-s7.crl
If a CRL file is missing and TreatMissingCrlAsWarning is enabled, the result remains valid but includes a warning.
If a certificate is found in a CRL with a revocation date before the validation time, verification fails.
When AKİS is unavailable, Viwo.Signer can create and use a dummy PFX certificate for testing.
Generated structure:
certs/kamusm/local-test
├── roots
│ ├── viwo-test-root-ca.crt
│ └── viwo-test-root-ca.pfx
└── signers
├── viwo-test-signer-ecdsa.crt
└── viwo-test-signer-ecdsa.pfx
The dummy root is loaded into the local custom trust store. It does not need to be installed into Windows Trusted Root Store.
Recommended setting:
{
"AutoInstallDummyRootToCurrentUser": false
}The test console includes menu-based operations such as:
1. Sign sample XML
2. Sign selected XML from Data folder
3. Verify selected signed XML
4. Verify custom XML path
5. Download KamuSM certificates
6. Create dummy PFX
7. Query KamuSM timestamp credit
8. Batch verify XML files
Actual menu options may vary depending on the current test project implementation.
A successful verification produces:
Verify Result: VALID
XML signature, certificate chain and timestamp verification completed successfully.
The detailed ESYA-like verification report includes:
VALID Temel Doğrulama - Temel doğrulama başarılı.
VALID İmza Değeri - İmza değeri doğrulandı.
VALID Referanslar - Referanslar geçerli.
VALID İmzacı Sertifikası - İmzacı sertifikası doğrulandı.
VALID DataObjectFormat - DataObjectFormat özelliği geçerli.
VALID SigningCertificate - SigningCertificate özelliği geçerli.
VALID SigningTime - İmza sertifikası imza zamanı(SigningTime) anında geçerli.
VALID TurkishESigProfile - İmza Türk imza profilleri içermiyor.
VALID SignatureTimeStamp - SignatureTimeStamp geçerli.
VALID Sertifika Detayları - Sertifika doğrulama detayları başarılı.
Detailed certificate checks include:
VALID İmzalama Algoritması Aynımı Kontrolü
VALID Seri Numarası Kontrolü
VALID Sertifika Geçerlilik Tarihi Kontrolü
VALID Sertifika Eklenti Kontrolü
VALID Versiyon Kontrolü
VALID SERTIFIKA_EXTENDED_KEY_USAGE_KONTROLU
VALID SİL / CRL Kontrolü
Viwo.Signer currently performs the following ESYA-like checks:
| ESYA-like Check | Status |
|---|---|
| Basic validation | Supported |
| Signature value validation | Supported |
| Reference digest validation | Supported |
| Signer certificate validation | Supported |
| DataObjectFormat validation | Supported |
| SigningCertificate validation | Supported |
| SigningTime validation | Supported |
| TurkishESigProfile reporting | Supported |
| SignatureTimeStamp validation | Supported |
| EncapsulatedTimeStamp validation | Supported |
| Timestamp mathematical signature validation | Supported |
| Timestamp content digest validation | Supported |
| Timestamp TSA certificate validation | Supported |
| Timestamp TSA CRL/SİL validation | Supported |
| Signer certificate chain validation | Supported |
| Signer certificate CRL/SİL validation | Supported |
| Local custom trust store | Supported |
| Windows Store independent validation | Supported |
Not yet implemented:
| Feature | Status |
|---|---|
| OCSP / ÇiSDuP online validation | Planned |
| ES-C / ES-X / ES-XL / ES-A | Planned / Out of current scope |
| CAdES | Out of current scope |
| PAdES | Out of current scope |
| ASiC | Out of current scope |
| Full ESYA policy engine | Planned / Optional |
dotnet restore
dotnet builddotnet run --project Viwo.Signer.TestBefore verifying signatures with local trust store, download certificates from the test console menu.
1. Start Viwo.Signer.Test
2. Choose "Download KamuSM certificates"
3. Verify that all manifest files are downloaded or skipped without errors
4. Create dummy PFX if AKİS is not available
5. Sign a sample XML
6. Verify the signed XML
7. Review the ESYA-like detailed verification report
Before production usage:
- Validate with real AKİS / mali mühür
- Validate with KamuSM production timestamp
- Verify documents with TÜBİTAK ESYA or another official validation tool
- Review generated XML signatures against GİB/e-Defter requirements
- Keep timestamp credentials secure
- Keep PIN values out of configuration files
- Do not commit PFX/private key files
- Maintain CRL files and certificate manifest updates
- Review legal compliance for your use case
Do not commit:
appsettings.Development.json
*.pfx
*.p12
*.key
*.pem
lisans.xml
PIN values
Production timestamp credentials
Real signed customer XML files
Use environment variables, user secrets or secure configuration providers for sensitive values.
This project is an independent implementation of XML/XAdES signing and verification workflows.
It is not an official TÜBİTAK, KamuSM, GİB or ESYA product.
Use in production requires your own technical, legal and regulatory validation.
Planned improvements:
- JSON/XML export for detailed verification reports
- Batch verification report summary
- Strict / Relaxed validation policy
- OCSP / ÇiSDuP support
- Improved profile presets:
- e-Defter
- Berat
- Envanter
- e-Fatura
- e-İrsaliye
- ApplicationResponse
- Multi-signature support
- Append / remove signature operations
- More detailed XAdES property validators
- NuGet packaging
- CI build pipeline