Yamgooo.SRI.Sign
1.0.4
dotnet add package Yamgooo.SRI.Sign --version 1.0.4
NuGet\Install-Package Yamgooo.SRI.Sign -Version 1.0.4
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="Yamgooo.SRI.Sign" Version="1.0.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Yamgooo.SRI.Sign" Version="1.0.4" />
<PackageReference Include="Yamgooo.SRI.Sign" />
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 Yamgooo.SRI.Sign --version 1.0.4
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Yamgooo.SRI.Sign, 1.0.4"
#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 Yamgooo.SRI.Sign@1.0.4
#: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=Yamgooo.SRI.Sign&version=1.0.4
#tool nuget:?package=Yamgooo.SRI.Sign&version=1.0.4
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
SRI Digital Signature Service
A professional .NET library for digital signature operations using XAdES signatures, specifically designed for SRI (Servicio de Rentas Internas) electronic invoicing in Ecuador.
Also available in Spanish: README_es.md
๐ Features
- XAdES Digital Signatures: Full support for XML Advanced Electronic Signatures
- Certificate Management: Flexible certificate loading from P12/PFX files and Base64
- Base64 Certificates: Full support for embedded Base64 certificates (ideal for cloud and containers)
- Async Operations: High-performance asynchronous signature operations
- Configuration Support: Multiple configuration options (appsettings.json, code-based, dynamic)
- Validation: Built-in signature validation and certificate verification
- Logging: Comprehensive logging with structured logging support
- Error Handling: Robust error handling with detailed error messages
- Performance Monitoring: Built-in performance metrics and timing
๐ฆ Installation
NuGet Package
dotnet add package Yamgooo.SRI.Sign
Manual Installation
git clone https://github.com/yamgooo/Sri.Sign.git
cd Sri.Sign
dotnet build
๐ ๏ธ Quick Start
1. Basic Usage (Dynamic Configuration)
using Yamgooo.SRI.Sign;
// Register the service
services.AddSriSignService();
// Use the service
var sriSignService = serviceProvider.GetRequiredService<ISriSignService>();
// Set certificate dynamically
sriSignService.SetDefaultCertificate("path/to/certificate.p12", "your-password");
// Sign XML content
var result = await sriSignService.SignAsync(xmlContent);
if (result.Success)
{
Console.WriteLine($"XML signed successfully in {result.ProcessingTimeMs}ms");
var signedXml = result.SignedXml;
}
else
{
Console.WriteLine($"Error: {result.ErrorMessage}");
}
2. Direct Certificate Usage
// Sign with specific certificate (no configuration needed)
var result = await sriSignService.SignAsync(
xmlContent,
"path/to/certificate.p12",
"your-password"
);
3. Base64 Certificate Usage
// Sign with Base64 certificate (ideal for cloud and containers)
var result = await sriSignService.SignWithBase64CertificateAsync(
xmlContent,
"MIIKsAIBAzCCCmwGCSqGSIb3DQEHAaCCCl0EggpZMIIKVTCCBQ...",
"your-password"
);
// Or set default Base64 certificate
sriSignService.SetDefaultBase64Certificate(certificateBase64, password);
var result = await sriSignService.SignWithDefaultBase64CertificateAsync(xmlContent);
4. Configuration-based Usage
appsettings.json
{
"SriSign": {
"CertificatePath": "Certificates/certificate.p12",
"CertificatePassword": "your-secure-password",
"CertificateBase64": "MIIKsAIBAzCCCmwGCSqGSIb3DQEHAaCCCl0EggpZMIIKVTCCBQ...",
"Base64CertificatePassword": "your-base64-password"
}
}
Program.cs
// Register with configuration
services.AddSriSignService(configuration);
// Use the service
var sriSignService = serviceProvider.GetRequiredService<ISriSignService>();
var result = await sriSignService.SignAsync(xmlContent);
5. Custom Configuration
var config = new SriSignConfiguration
{
CertificatePath = "path/to/certificate.p12",
CertificatePassword = "your-password",
CertificateBase64 = "MIIKsAIBAzCCCmwGCSqGSIb3DQEHAaCCCl0EggpZMIIKVTCCBQ...",
Base64CertificatePassword = "your-base64-password"
};
services.AddSriSignService(config);
๐ API Reference
ISriSignService Interface
SignAsync Methods
// Sign with default certificate configuration (prioritizes Base64 if configured)
Task<SignatureResult> SignAsync(string xmlContent);
// Sign with specific certificate
Task<SignatureResult> SignAsync(string xmlContent, string certificatePath, string password);
// Sign with specific Base64 certificate
Task<SignatureResult> SignWithBase64CertificateAsync(string xmlContent, string certificateBase64, string password);
// Sign with default Base64 certificate
Task<SignatureResult> SignWithDefaultBase64CertificateAsync(string xmlContent);
Validation
// Validate a signed XML document
bool ValidateSignature(string signedXml);
// Validate a Base64 certificate
bool ValidateBase64Certificate(string certificateBase64, string password);
Configuration
// Set default certificate for subsequent operations
void SetDefaultCertificate(string certificatePath, string password);
// Set default Base64 certificate for subsequent operations
void SetDefaultBase64Certificate(string certificateBase64, string password);
SignatureResult
public class SignatureResult
{
public bool Success { get; set; }
public string SignedXml { get; set; }
public string ErrorMessage { get; set; }
public DateTime SignatureTimestamp { get; set; }
public long ProcessingTimeMs { get; set; }
}
๐ง Configuration Options
Service Registration Methods
// From appsettings.json
services.AddSriSignService(configuration, "SriSign");
// With custom configuration object
services.AddSriSignService(customConfig);
// With direct certificate parameters
services.AddSriSignService("certificate.p12", "password");
// Without configuration (for dynamic use)
services.AddSriSignService();
Configuration Validation
The service automatically validates:
- Certificate file existence and accessibility
- Certificate file size (1KB - 10MB)
- Certificate password validity
- Certificate expiration
- Private key availability
- Valid Base64 format for embedded certificates
- Automatic Base64 format cleaning (line breaks, PEM headers, etc.)
๐ Examples
Base64 Certificate Example
public class Base64CertificateExample
{
private readonly ISriSignService _sriSignService;
public async Task<SignatureResult> SignWithBase64CertificateAsync(string xmlContent)
{
// Convert certificate file to Base64 (one-time operation)
var certificateBytes = File.ReadAllBytes("certificate.p12");
var certificateBase64 = Convert.ToBase64String(certificateBytes);
var password = "your-password";
// Validate Base64 certificate before using
if (!_sriSignService.ValidateBase64Certificate(certificateBase64, password))
{
throw new InvalidOperationException("Invalid Base64 certificate");
}
// Sign with Base64 certificate
return await _sriSignService.SignWithBase64CertificateAsync(xmlContent, certificateBase64, password);
}
public async Task<SignatureResult> SignWithConfiguredBase64Async(string xmlContent)
{
// Configure default Base64 certificate
var certificateBase64 = Environment.GetEnvironmentVariable("SRI_CERTIFICATE_BASE64");
var password = Environment.GetEnvironmentVariable("SRI_CERTIFICATE_PASSWORD");
_sriSignService.SetDefaultBase64Certificate(certificateBase64, password);
// Sign using default configuration
return await _sriSignService.SignAsync(xmlContent);
}
}
Complete SRI Invoice Signing Example
public class InvoiceSigningService
{
private readonly ISriSignService _sriSignService;
private readonly ILogger<InvoiceSigningService> _logger;
public InvoiceSigningService(ISriSignService sriSignService, ILogger<InvoiceSigningService> logger)
{
_sriSignService = sriSignService;
_logger = logger;
}
public async Task<SignatureResult> SignInvoiceAsync(string invoiceXml)
{
try
{
// Sign the invoice XML
var result = await _sriSignService.SignAsync(invoiceXml);
if (result.Success)
{
_logger.LogInformation("Invoice signed successfully");
// Validate the signature
if (_sriSignService.ValidateSignature(result.SignedXml))
{
_logger.LogInformation("Signature validation passed");
}
else
{
_logger.LogWarning("Signature validation failed");
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error signing invoice");
return SignatureResult.CreateFailure(ex.Message);
}
}
}
Multiple Certificate Management
public class MultiTenantSigningService
{
private readonly ISriSignService _sriSignService;
public async Task<SignatureResult> SignForTenantAsync(string xmlContent, string tenantId)
{
// Get tenant-specific certificate
var certificatePath = GetTenantCertificatePath(tenantId);
var certificatePassword = GetTenantCertificatePassword(tenantId);
// Sign with tenant-specific certificate
return await _sriSignService.SignAsync(xmlContent, certificatePath, certificatePassword);
}
}
๐ Security Considerations
- Certificate Storage: Store certificates securely and never commit them to source control
- Base64 Certificates: Ideal for containers and cloud services, store in environment variables or secret services
- Password Management: Use secure configuration providers (Azure Key Vault, AWS Secrets Manager, etc.)
- File Permissions: Ensure certificate files have appropriate access permissions
- Network Security: Use HTTPS for all network communications
- Logging: Be careful not to log sensitive information like certificate passwords
- Certificate Rotation: Consider rotating certificates regularly, especially in production environments
๐งช Testing
Unit Testing Example
[Test]
public async Task SignAsync_WithValidXml_ReturnsSuccess()
{
// Arrange
var mockLogger = new Mock<ILogger<SriSignService>>();
var service = new SriSignService(mockLogger.Object);
var xmlContent = "<test>content</test>";
var certificatePath = "test-cert.p12";
var password = "test-password";
// Act
var result = await service.SignAsync(xmlContent, certificatePath, password);
// Assert
Assert.IsNotNull(result);
// Add more specific assertions based on your test certificate
}
๐ Performance
The service is optimized for high-performance operations:
- Async Operations: All I/O operations are asynchronous
- Memory Efficient: Uses streaming for large XML documents
- Caching: Certificate loading is optimized
- Metrics: Built-in performance monitoring
Typical performance metrics:
- Small XML (< 1KB): ~50-100ms
- Medium XML (1-10KB): ~100-200ms
- Large XML (10-100KB): ~200-500ms
๐ฆ Dependencies
- .NET 9.0: Target framework
- FirmaXadesNet: XAdES signature implementation
- Microsoft.Extensions.Configuration: Configuration support
- Microsoft.Extensions.Logging: Logging infrastructure
- Microsoft.Extensions.Options: Options pattern support
๐ค Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Support
- Issues: GitHub Issues
- Documentation: Wiki
- Email: erikportillapesantez@outlook.com
Made with โค๏ธ for the Ecuadorian developer community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Infoware.FirmaXadesNet (>= 1.1.47)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 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.