Skip to content

Commit fb11729

Browse files
committed
Refactor cryptographic settings for thread safety
Moved cryptographic settings (`SignatureAlgorithm`, `SignaturePadding`) from the static `CredentialSettings` class to instance-level properties in the `Credential` class, ensuring thread safety and better encapsulation. Updated `SignData` and `VerifyData` methods in `Credential` and `PrivateKey` to use instance-specific parameters. Modified `ConfigureAlgorithmForInvoicing` and `ConfigureAlgorithmForXmlDownloader` to return `ICredential` for a fluent interface. Enhanced `ICredential` and `IPrivateKey` interfaces to support the new design. Removed unused code and updated XML documentation. Incremented version to 4.0.340.
1 parent d945754 commit fb11729

File tree

6 files changed

+59
-40
lines changed

6 files changed

+59
-40
lines changed

Common/CredentialSettings.cs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
1-
using System.Security.Cryptography;
2-
1+

32
namespace Fiscalapi.Credentials.Common;
43

54
public static class CredentialSettings
65
{
7-
/// <summary>
8-
/// Default algorithm to sing mexican invoicing
9-
/// </summary>
10-
public static HashAlgorithmName SignatureAlgorithm { get; set; } = HashAlgorithmName.SHA1;
11-
12-
/// <summary>
13-
/// Default signature padding
14-
/// </summary>
15-
public static RSASignaturePadding SignaturePadding { get; set; } = RSASignaturePadding.Pkcs1;
16-
17-
/// <summary>
18-
/// Default algorithm to digest SAT services
19-
/// </summary>
20-
public static HashAlgorithm HashAlgorithm { get; set; } = SHA1.Create();
6+
//Algoritmos ahora son parte de la instancia (thread-safe)
217

228
/// <summary>
239
/// Path of the CadenaOriginal.xslt file to do XML data transformation using an XSLT stylesheet.

Core/Credential.cs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ public Credential(ICertificate certificate, IPrivateKey privateKey)
2828
PemPrivateKey = privateKey.GetPemRepresentation();
2929

3030
certificateWithPrivateKey = X509Certificate2.CreateFromPem(PemCertificate, PemPrivateKey);
31+
32+
// Default algorithm is SHA256 (for invoicing)
33+
SignatureAlgorithm = HashAlgorithmName.SHA256;
34+
35+
// Default padding is Pkcs1 (used for both invoicing and XML downloader)
36+
SignaturePadding = RSASignaturePadding.Pkcs1;
3137
}
3238

3339
/// <summary>
@@ -50,6 +56,16 @@ public Credential(ICertificate certificate, IPrivateKey privateKey)
5056

5157
public string PemPrivateKey { get; }
5258

59+
/// <summary>
60+
/// Signature algorithm used for signing data. Default is SHA256 (for invoicing).
61+
/// </summary>
62+
public HashAlgorithmName SignatureAlgorithm { get; set; }
63+
64+
/// <summary>
65+
/// Signature padding used for signing data. Default is Pkcs1 (used for both invoicing and XML downloader).
66+
/// </summary>
67+
public RSASignaturePadding SignaturePadding { get; set; }
68+
5369
public byte[] CreatePFX()
5470
{
5571
var pfxBytes = certificateWithPrivateKey.Export(X509ContentType.Pfx, PasswordPhrase);
@@ -72,11 +88,10 @@ private string GetPrivateKeyPemRepresentation()
7288
/// </summary>
7389
/// <param name="toSign">string to be signed</param>
7490
/// <returns>signed bytes</returns>
75-
/// see CredentialSettings class to see signature parameters
7691
public byte[] SignData(string toSign)
7792
{
7893
//Sing and get signed bytes array
79-
var signedBytes = PrivateKey.SignData(toSign);
94+
var signedBytes = PrivateKey.SignData(toSign, SignatureAlgorithm, SignaturePadding);
8095

8196
return signedBytes;
8297
}
@@ -89,7 +104,7 @@ public byte[] SignData(string toSign)
89104
/// <returns>True when the signature is valid, otherwise false</returns>
90105
public bool VerifyData(byte[] dataToVerify, byte[] signedData)
91106
{
92-
var isValid = PrivateKey.VerifyData(dataToVerify, signedData);
107+
var isValid = PrivateKey.VerifyData(dataToVerify, signedData, SignatureAlgorithm, SignaturePadding);
93108

94109
return isValid;
95110
}
@@ -212,19 +227,21 @@ public string GetOriginalStringByXmlString(string xmlAsString)
212227

213228
/// <summary>
214229
/// Configure the Signature algorithm to do invoicing, using the donetcfdi/invoicing library.
215-
/// The default value is HashAlgorithmName.SHA1 (used for downloading xml), call ConfigureAlgorithmForInvoicing() methost to set HashAlgorithmName.SHA256 when you need to sign invoices.
230+
/// Sets HashAlgorithmName.SHA256 for signing invoices. Returns this for fluent interface.
216231
/// </summary>
217-
public void ConfigureAlgorithmForInvoicing()
232+
public ICredential ConfigureAlgorithmForInvoicing()
218233
{
219-
CredentialSettings.SignatureAlgorithm = HashAlgorithmName.SHA256;
234+
SignatureAlgorithm = HashAlgorithmName.SHA256;
235+
return this;
220236
}
221237

222238
/// <summary>
223239
/// Configure the Signature algorithm to do xml-downloader, using the donetcfdi/xml-downloader library.
224-
/// The default value is HashAlgorithmName.SHA1 (used for downloading xml), call ConfigureAlgorithmForXmlDownloader() method to set HashAlgorithmName.SHA1 when you need to download xml.
240+
/// Sets HashAlgorithmName.SHA1 for downloading xml. Returns this for fluent interface.
225241
/// </summary>
226-
public void ConfigureAlgorithmForXmlDownloader()
242+
public ICredential ConfigureAlgorithmForXmlDownloader()
227243
{
228-
CredentialSettings.SignatureAlgorithm = HashAlgorithmName.SHA1;
244+
SignatureAlgorithm = HashAlgorithmName.SHA1;
245+
return this;
229246
}
230247
}

Core/ICredential.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Fiscalapi.Credentials.Common;
1+
using System.Security.Cryptography;
2+
using Fiscalapi.Credentials.Common;
23

34
namespace Fiscalapi.Credentials.Core;
45

@@ -27,6 +28,16 @@ public interface ICredential
2728
/// </summary>
2829
CredentialType CredentialType { get; }
2930

31+
/// <summary>
32+
/// Signature algorithm used for signing data. Default is SHA256 (for invoicing).
33+
/// </summary>
34+
HashAlgorithmName SignatureAlgorithm { get; set; }
35+
36+
/// <summary>
37+
/// Signature padding used for signing data. Default is Pkcs1 (used for both invoicing and XML downloader).
38+
/// </summary>
39+
RSASignaturePadding SignaturePadding { get; set; }
40+
3041
byte[] CreatePFX();
3142

3243
/// <summary>
@@ -87,13 +98,13 @@ public interface ICredential
8798

8899
/// <summary>
89100
/// Configure the Signature algorithm to do invoicing, using the donetcfdi/invoicing library.
90-
/// The default value is HashAlgorithmName.SHA1 (used for downloading xml), call ConfigureAlgorithmForInvoicing() methost to set HashAlgorithmName.SHA256 when you need to sign invoices.
101+
/// Sets HashAlgorithmName.SHA256 for signing invoices. Returns this for fluent interface.
91102
/// </summary>
92-
public void ConfigureAlgorithmForInvoicing();
103+
public ICredential ConfigureAlgorithmForInvoicing();
93104

94105
/// <summary>
95106
/// Configure the Signature algorithm to do xml-downloader, using the donetcfdi/xml-downloader library.
96-
/// The default value is HashAlgorithmName.SHA1 (used for downloading xml), call ConfigureAlgorithmForXmlDownloader() method to set HashAlgorithmName.SHA1 when you need to download xml.
107+
/// Sets HashAlgorithmName.SHA1 for downloading xml. Returns this for fluent interface.
97108
/// </summary>
98-
public void ConfigureAlgorithmForXmlDownloader();
109+
public ICredential ConfigureAlgorithmForXmlDownloader();
99110
}

Core/IPrivateKey.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,18 @@ public interface IPrivateKey
4242
/// Sign some data
4343
/// </summary>
4444
/// <param name="toSign">string to be signed</param>
45+
/// <param name="algorithm">Hash algorithm to use for signing</param>
46+
/// <param name="padding">Signature padding to use</param>
4547
/// <returns>signed bytes</returns>
46-
/// see CredentialSettings class
47-
byte[] SignData(string toSign);
48+
byte[] SignData(string toSign, HashAlgorithmName algorithm, RSASignaturePadding padding);
4849

4950
/// <summary>
5051
/// Verify the signature of some data
5152
/// </summary>
5253
/// <param name="dataToVerify">original data in bytes</param>
5354
/// <param name="signedData">signed data in bytes</param>
55+
/// <param name="algorithm">Hash algorithm to use for verification</param>
56+
/// <param name="padding">Signature padding to use</param>
5457
/// <returns>True when the signature is valid, otherwise false</returns>
55-
bool VerifyData(byte[] dataToVerify, byte[] signedData);
58+
bool VerifyData(byte[] dataToVerify, byte[] signedData, HashAlgorithmName algorithm, RSASignaturePadding padding);
5659
}

Core/PrivateKey.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,16 @@ public string GetPemRepresentation()
6363
/// Sign some data
6464
/// </summary>
6565
/// <param name="toSign">string to be signed</param>
66+
/// <param name="algorithm">Hash algorithm to use for signing</param>
67+
/// <param name="padding">Signature padding to use</param>
6668
/// <returns>signed bytes</returns>
67-
/// see CredentialSettings class
68-
public byte[] SignData(string toSign)
69+
public byte[] SignData(string toSign, HashAlgorithmName algorithm, RSASignaturePadding padding)
6970
{
7071
//get bytes array to sing
7172
var bytesToSign = toSign.GetBytes();
7273

7374
//Sing and get signed bytes array
74-
var signedBytes = RsaPrivateKey.SignData(bytesToSign, CredentialSettings.SignatureAlgorithm, CredentialSettings.SignaturePadding);
75+
var signedBytes = RsaPrivateKey.SignData(bytesToSign, algorithm, padding);
7576

7677
//Converts signed bytes to base64
7778
return signedBytes;
@@ -82,14 +83,15 @@ public byte[] SignData(string toSign)
8283
/// </summary>
8384
/// <param name="dataToVerify">original data in bytes</param>
8485
/// <param name="signedData">signed data in bytes</param>
86+
/// <param name="algorithm">Hash algorithm to use for verification</param>
87+
/// <param name="padding">Signature padding to use</param>
8588
/// <returns>True when the signature is valid, otherwise false</returns>
86-
public bool VerifyData(byte[] dataToVerify, byte[] signedData)
89+
public bool VerifyData(byte[] dataToVerify, byte[] signedData, HashAlgorithmName algorithm, RSASignaturePadding padding)
8790
{
8891
try
8992
{
9093
//Validation
91-
var isValid = RsaPrivateKey.VerifyData(dataToVerify, signedData, CredentialSettings.SignatureAlgorithm,
92-
CredentialSettings.SignaturePadding);
94+
var isValid = RsaPrivateKey.VerifyData(dataToVerify, signedData, algorithm, padding);
9395

9496

9597
return isValid;

fiscalapi-credentials.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
5-
<Version>4.0.97</Version>
5+
<Version>4.0.340</Version>
66
<AssemblyVersion>$(Version)</AssemblyVersion>
77
<FileVersion>$(Version)</FileVersion>
88
<PackageVersion>$(Version)</PackageVersion>

0 commit comments

Comments
 (0)