Skip to content
20 changes: 1 addition & 19 deletions CTe.Utils/CTe/ExtCTe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Xml;
Expand Down Expand Up @@ -297,7 +296,7 @@ public static infCTeSupl QrCode(this CteEletronica cte, X509Certificate2 certifi
&& cte.infCte.ide.tpEmis != tpEmis.teSVCSP
)
{
var assinatura = Convert.ToBase64String(CreateSignaturePkcs1(certificadoDigital, encoding.GetBytes(chave)));
var assinatura = Convert.ToBase64String(AssinaturaDigital.CriarAssinaturaPkcs1(certificadoDigital, encoding.GetBytes(chave)));
qrCode.Append("&sign=");
qrCode.Append(assinatura);
}
Expand All @@ -308,23 +307,6 @@ public static infCTeSupl QrCode(this CteEletronica cte, X509Certificate2 certifi
};
}

private static byte[] CreateSignaturePkcs1(X509Certificate2 certificadoDigital, byte[] Value)
{
var rsa = certificadoDigital.GetRSAPrivateKey();

RSAPKCS1SignatureFormatter rsaF = new RSAPKCS1SignatureFormatter(rsa);

SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

byte[] hash = null;

hash = sha1.ComputeHash(Value);

rsaF.SetHashAlgorithm("SHA1");

return rsaF.CreateSignature(hash);
}

public static void SalvarXmlEmDisco(this CteEletronica cte, ConfiguracaoServico configuracaoServico = null)
{
var instanciaServico = configuracaoServico ?? ConfiguracaoServico.Instancia;
Expand Down
20 changes: 1 addition & 19 deletions CTe.Utils/CTe/ExtCTeOs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using DFe.Utils.Assinatura;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Xml;
Expand Down Expand Up @@ -72,7 +71,7 @@ public static infCTeSupl QrCode(this CteEletronica cte, X509Certificate2 certifi
&& cte.InfCte.ide.tpEmis != tpEmis.teSVCSP
)
{
var assinatura = Convert.ToBase64String(CreateSignaturePkcs1(certificadoDigital, encoding.GetBytes(chave)));
var assinatura = Convert.ToBase64String(AssinaturaDigital.CriarAssinaturaPkcs1(certificadoDigital, encoding.GetBytes(chave)));
qrCode.Append("&sign=");
qrCode.Append(assinatura);
}
Expand All @@ -83,23 +82,6 @@ public static infCTeSupl QrCode(this CteEletronica cte, X509Certificate2 certifi
};
}

private static byte[] CreateSignaturePkcs1(X509Certificate2 certificadoDigital, byte[] Value)
{
var rsa = certificadoDigital.GetRSAPrivateKey();

RSAPKCS1SignatureFormatter rsaF = new RSAPKCS1SignatureFormatter(rsa);

SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

byte[] hash = null;

hash = sha1.ComputeHash(Value);

rsaF.SetHashAlgorithm("SHA1");

return rsaF.CreateSignature(hash);
}

public static string Chave(this CteEletronica cte)
{
var chave = cte.InfCte.Id.Substring(3, 44);
Expand Down
4 changes: 0 additions & 4 deletions DFe.Testes/DFe.Testes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,4 @@
<ProjectReference Include="..\NFe.Utils\NFe.Utils.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Valores\DadosDeTeste\" />
</ItemGroup>

</Project>
48 changes: 48 additions & 0 deletions DFe.Testes/Utils/Assinatura/AssinaturaDigitalTesteUnitario.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Security.Cryptography;
using System.Text;
using DadosDeTestes.AssinaturaDigital;
using DFe.Utils.Assinatura;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DFe.Testes.Utils.Assinatura;

[TestClass]
public class AssinaturaDigitalTesteUnitario
{
[TestMethod(displayName: "Dado dados para geração do hash sha1 bytes, quando obter hash sha1 bytes, então deve obter hash sha1 em bytes igual do SHA1CryptoServiceProvider.")]
[DynamicData(nameof(AssinaturaDigitalTesteDados.ObterDadosParaGeracaoDoHashSha1Bytes), typeof(AssinaturaDigitalTesteDados), DynamicDataSourceType.Method)]
public void DadoDadosParaGeracaoDoHashSha1BytesQuandoObterHashSha1BytesEntaoDeveObterHashSha1EmBytesIgualDoSha1CryptoServiceProvider(string dadosEmString)
{
// Arrange
var dadosEmBytes = Encoding.UTF8.GetBytes(dadosEmString);
var bytesEsperados = ObterHashSha1BytesUsandoSha1CryptoServiceProvider(dadosEmBytes);

// Act
var bytesRetornado = AssinaturaDigital.ObterHashSha1Bytes(dadosEmBytes);

// Assert
CollectionAssert.AreEqual(bytesEsperados, bytesRetornado);
}

[TestMethod(displayName: "Dado dados para geração do hash sha1 bytes, quando obter hash sha1 bytes, então deve obter hash sha1 em bytes.")]
[DynamicData(nameof(AssinaturaDigitalTesteDados.ObterDadosParaGeracaoDoHashSha1BytesEValorEsperado), typeof(AssinaturaDigitalTesteDados), DynamicDataSourceType.Method)]
public void DadoDadosParaGeracaoDoHashSha1BytesQuandoObterHashSha1BytesEntaoDeveObterHashSha1EmBytes(string dadosEmString, byte[] bytesEsperados)
{
// Arrange
var dadosEmBytes = Encoding.UTF8.GetBytes(dadosEmString);

// Act
var bytesRetornado = AssinaturaDigital.ObterHashSha1Bytes(dadosEmBytes);

// Assert
CollectionAssert.AreEqual(bytesEsperados, bytesRetornado);
}

private byte[] ObterHashSha1BytesUsandoSha1CryptoServiceProvider(byte[] dados)
{
var sha1 = new SHA1CryptoServiceProvider();
var hashSha1Bytes = sha1.ComputeHash(dados);

return hashSha1Bytes;
}
}
34 changes: 34 additions & 0 deletions DFe.Utils/Assinatura/AssinaturaDigital.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */
/********************************************************************************/
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;
Expand Down Expand Up @@ -82,5 +83,38 @@ public static SignatureZeus Assina<T>(T objeto, string id, X509Certificate2 cert
var assinatura = FuncoesXml.XmlStringParaClasse<Classes.Assinatura.Signature>(xmlDigitalSignature.OuterXml);
return assinatura;
}

/// <summary>
/// Gera uma assinatura digital no formato PKCS1 utilizando o algoritmo RSA com SHA-1.
/// </summary>
/// <param name="certificado">Certificado digital com chave privada usada para assinar.</param>
/// <param name="valor">Dados a serem assinados em formato de array de bytes.</param>
/// <returns>Assinatura digital como um array de bytes.</returns>
public static byte[] CriarAssinaturaPkcs1(X509Certificate2 certificado, byte[] valor)
{
var rsa = certificado.GetRSAPrivateKey();

var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa);
rsaFormatter.SetHashAlgorithm("SHA1");

var hashSha1Bytes = ObterHashSha1Bytes(valor);

var assinatura = rsaFormatter.CreateSignature(hashSha1Bytes);

return assinatura;
}

/// <summary>
/// Obtém o hash SHA-1 em formato byte array a partir de um array de bytes informado.
/// </summary>
public static byte[] ObterHashSha1Bytes(byte[] dados)
{
using (var sha1 = SHA1.Create())
{
var sha1HashBytes = sha1.ComputeHash(dados);

return sha1HashBytes;
}
}
}
}
28 changes: 28 additions & 0 deletions DadosDeTestes/AssinaturaDigital/AssinaturaDigitalDadosDeTeste.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Security.Cryptography;

namespace DadosDeTestes.AssinaturaDigital;

public class AssinaturaDigitalTesteDados
{
public static IEnumerable<object[]> ObterDadosParaGeracaoDoHashSha1Bytes()
{
return new List<object[]>
{
new object[] { "92037465012398765432100011223344556677889900|2|1|F1A9B237CD8800FFE234A9912B674CFA1" },
new object[] { "87122345099887766554433221100009988776655443" },
new object[] { "73456789101112131415161718192021222324252627" },
new object[] { "65829374618273645564738291028374618273645564" }
};
}

public static IEnumerable<object[]> ObterDadosParaGeracaoDoHashSha1BytesEValorEsperado()
{
return new List<object[]>
{
new object[] { "92037465012398765432100011223344556677889900|2|1|F1A9B237CD8800FFE234A9912B674CFA1", new byte[] { 128, 55, 179, 49, 198, 97, 206, 43, 246, 208, 112, 183, 231, 3, 23, 105, 114, 184, 33, 153 }},
new object[] { "87122345099887766554433221100009988776655443", new byte[] { 151, 153, 16, 228, 170, 100, 76, 248, 192, 58, 160, 126, 157, 224, 171, 233, 75, 23, 118, 67 }},
new object[] { "73456789101112131415161718192021222324252627", new byte[] { 71, 100, 124, 212, 171, 46, 181, 47, 206, 96, 227, 230, 215, 8, 14, 131, 167, 214, 99, 181 }},
new object[] { "65829374618273645564738291028374618273645564", new byte[] { 147, 88, 158, 178, 38, 247, 111, 70, 151, 152, 182, 14, 69, 18, 129, 97, 157, 47, 222, 50 }}
};
}
}
15 changes: 15 additions & 0 deletions DadosDeTestes/NFe/Utils/ConversaoDadosDeTeste.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace DadosDeTestes.NFe.Utils;

public class ConversaoDadosDeTeste
{
public static IEnumerable<object[]> ObterDadosParaGerarHashSha1DeStringEValorEsperado()
{
return new List<object[]>
{
new object[] { "92037465012398765432100011223344556677889900|2|1|F1A9B237CD8800FFE234A9912B674CFA1", "8037b331c661ce2bf6d070b7e703176972b82199" },
new object[] { "87122345099887766554433221100009988776655443|1|2|9CFD3321AAC4900BDEAFA1105BC088119", "5994d3d62ca107c89677e7bede2f1e6a9371d9da" },
new object[] { "73456789101112131415161718192021222324252627|2|2|A7C44B8D56E9002FAB1133DCE5AA784C3", "ebbb014e73ff18fec652350da4a24907fad21297" },
new object[] { "65829374618273645564738291028374618273645564|1|1|B21C9D77E04A00BBF5C21EA39988D10AA", "19f80bbd273e606d206880f79ea56a671b263586" }
};
}
}
23 changes: 2 additions & 21 deletions MDFe.Classes/Extensoes/ExtMDFe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
using MDFe.Utils.Validacao;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using MDFEletronico = MDFe.Classes.Informacoes.MDFe;
Expand Down Expand Up @@ -161,7 +160,7 @@ public static MDFEletronico Assina(this MDFEletronico mdfe, EventHandler<string>
if (mdfe.InfMDFe.Ide.TpEmis == MDFeTipoEmissao.Contingencia)
{
var encoding = Encoding.UTF8;
var sign = Convert.ToBase64String(CreateSignaturePkcs1(config.X509Certificate2, encoding.GetBytes(mdfe.Chave())));
var sign = Convert.ToBase64String(AssinaturaDigital.CriarAssinaturaPkcs1(config.X509Certificate2, encoding.GetBytes(mdfe.Chave())));
mdfe.InfMDFeSupl.QrCodMDFe += "&sign=" + sign;
}

Expand Down Expand Up @@ -254,7 +253,7 @@ public static MdfeInfMDFeSupl QrCode(this MDFEletronico mdfe, X509Certificate2 c
switch (mdfe.InfMDFe.Ide.TpEmis)
{
case MDFeTipoEmissao.Contingencia:
var assinatura = Convert.ToBase64String(CreateSignaturePkcs1(certificadoDigital, encoding.GetBytes(mdfe.Chave())));
var assinatura = Convert.ToBase64String(AssinaturaDigital.CriarAssinaturaPkcs1(certificadoDigital, encoding.GetBytes(mdfe.Chave())));
qrCode.Append("&sign=");
qrCode.Append(assinatura);
break;
Expand All @@ -265,23 +264,5 @@ public static MdfeInfMDFeSupl QrCode(this MDFEletronico mdfe, X509Certificate2 c
QrCodMDFe = qrCode.ToString()
};
}

private static byte[] CreateSignaturePkcs1(X509Certificate2 certificado, byte[] Value)
{
var rsa = certificado.GetRSAPrivateKey();

RSAPKCS1SignatureFormatter rsaF = new RSAPKCS1SignatureFormatter(rsa);

SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

byte[] hash = null;

hash = sha1.ComputeHash(Value);

rsaF.SetHashAlgorithm("SHA1");

return rsaF.CreateSignature(hash);

}
}
}
18 changes: 18 additions & 0 deletions NFe.Utils.Testes/ConversaoTesteUnitario.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using DadosDeTestes.NFe.Utils;
using Xunit;

namespace NFe.Utils.Testes;

public class ConversaoTesteUnitario
{
[Theory(DisplayName = "Dado dados em string para geração do hex sha1 de string, quando obter hex sha1 de string, então deve obter hex sha1 de string.")]
[MemberData(nameof(ConversaoDadosDeTeste.ObterDadosParaGerarHashSha1DeStringEValorEsperado), MemberType = typeof(ConversaoDadosDeTeste))]
public void DadoDadosEmStringParaGeracaoDoHexSha1DeStringQuandoObterHexSha1DeStringEntaoDeveObterHexSha1DeString(string dadosEmString, string stringEsperada)
{
// Act
var valorRetornado = Conversao.ObterHexSha1DeString(dadosEmString);

// Assert
Assert.Equal(stringEsperada, valorRetornado);
}
}
1 change: 1 addition & 0 deletions NFe.Utils.Testes/NFe.Utils.Testes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\DadosDeTestes\DadosDeTestes.csproj" />
<ProjectReference Include="..\DFe.Classes\DFe.Classes.csproj" />
<ProjectReference Include="..\NFe.Classes\NFe.Classes.csproj" />
<ProjectReference Include="..\NFe.Utils\NFe.Utils.csproj" />
Expand Down
8 changes: 4 additions & 4 deletions NFe.Utils/Conversao.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
/* Rua Comendador Francisco josé da Cunha, 111 - Itabaiana - SE - 49500-000 */
/********************************************************************************/
using System;
using System.Security.Cryptography;
using System.Text;
using DFe.Classes.Flags;
using DFe.Utils.Assinatura;
using NFe.Classes.Informacoes.Detalhe.Tributacao.Estadual.Tipos;
using NFe.Classes.Informacoes.Emitente;
using NFe.Classes.Informacoes.Identificacao.Tipos;
Expand Down Expand Up @@ -231,10 +231,10 @@ public static string ObterHexSha1DeString(string s)
{
var bytes = Encoding.UTF8.GetBytes(s);

var sha1 = SHA1.Create();
var hashBytes = sha1.ComputeHash(bytes);
var hashSha1Bytes = AssinaturaDigital.ObterHashSha1Bytes(bytes);
var hexSha1DeString = ObterHexDeByteArray(hashSha1Bytes);

return ObterHexDeByteArray(hashBytes);
return hexSha1DeString;
}

/// <summary>
Expand Down
11 changes: 3 additions & 8 deletions NFe.Utils/InfRespTec/GerarHashCSRT.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Security.Cryptography;
using System.Text;
using DFe.Utils.Assinatura;

namespace Shared.NFe.Utils.InfRespTec
{
Expand All @@ -22,13 +22,8 @@ public static string HashCSRT(string csrt, string chave, Encoding encoding = nul

var data = encoding.GetBytes(csrtChave);

string chaveBase64;

using (SHA1CryptoServiceProvider cryptoTransformSha1 = new SHA1CryptoServiceProvider())
{
var hash = cryptoTransformSha1.ComputeHash(data);
chaveBase64 = Convert.ToBase64String(hash);
}
var sha1HashBytes = AssinaturaDigital.ObterHashSha1Bytes(data);
var chaveBase64 = Convert.ToBase64String(sha1HashBytes);

return chaveBase64;
}
Expand Down