Ir para conteúdo
  • Cadastre-se

Envio para PedidoEnvioLoteRPS versao 2 NFSE São Paulo, com erro 1206 Assinatura Digital do RPS incorreta - String verificada


Ver Solução Respondido por Alexandre Jansen,
  • Este tópico foi criado há 137 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Bom dia @Alexandre Jansen

Para resolver esse erro na unit ISSSãoPaulo.Provider, na rotina em questão, adicionei a variável lTamanhoInscricaoMunicipal: Integer; e, caso a versão seja ve200, alterei o tamanho da inscrição municipal para 12 caracteres. Conforme especificado no Manual, versão 3.3.4, na página 20, há um trecho que deve ser impresso.

image.thumb.png.6fce85f556acbc30fa48dd6369149a72.png

 

Na rotina abaixo em vermelho foi o que alterei.

procedure TACBrNFSeProviderISSSaoPaulo.AssinaturaAdicional(Nota: TNotaFiscal);
var
  sSituacao, sISSRetido, sCPFCNPJTomador, sIndTomador, sTomador,
  sCPFCNPJInter, sIndInter, sISSRetidoInter, sInter, sAssinatura: string;
  lTamanhoInscricaoMunicipal: integer;
begin
  with Nota do
  begin
    sSituacao := EnumeradoToStr(NFSe.SituacaoNfse, ['N', 'C'], [snNormal, snCancelado]);

    sISSRetido := EnumeradoToStr(NFSe.Servico.Valores.IssRetido,
                                 ['N', 'S'], [stNormal, stRetencao]);

    // Tomador do Serviço
    sCPFCNPJTomador := OnlyNumber(NFSe.Tomador.IdentificacaoTomador.CpfCnpj);

    if Length(sCPFCNPJTomador) = 11 then
      sIndTomador := '1'
    else
      if Length(sCPFCNPJTomador) = 14 then
        sIndTomador := '2'
      else
        sIndTomador := '3';

    sTomador := sIndTomador + Poem_Zeros(sCPFCNPJTomador, 14);

    // Prestador Intermediario
    sCPFCNPJInter := OnlyNumber(NFSe.Intermediario.Identificacao.CpfCnpj);

    if Length(sCPFCNPJInter) = 11 then
      sIndInter := '1'
    else
      if Length(sCPFCNPJInter) = 14 then
        sIndInter := '2'
      else
        sIndInter := '3';

    sISSRetidoInter := EnumeradoToStr(NFSe.Intermediario.IssRetido,
                                      ['N', 'S'], [stNormal, stRetencao]);

    if sIndInter <> '3' then
      sInter := sIndInter + Poem_Zeros(sCPFCNPJInter, 14) + sISSRetidoInter
    else
      sInter := '';

    if TACBrNFSeX(FAOwner).Configuracoes.Geral.Versao = ve200 then
      lTamanhoInscricaoMunicipal := 12
    else
      lTamanhoInscricaoMunicipal := 8;


    sAssinatura := Poem_Zeros(NFSe.Prestador.IdentificacaoPrestador.InscricaoMunicipal, lTamanhoInscricaoMunicipal) +
                   PadRight(NFSe.IdentificacaoRps.Serie, 5, ' ') +
                   Poem_Zeros(NFSe.IdentificacaoRps.Numero, 12) +
                   FormatDateTime('yyyymmdd', NFse.DataEmissao) +
                   TipoTributacaoRPSToStr(NFSe.TipoTributacaoRPS) +
                   sSituacao +
                   sISSRetido +
                   Poem_Zeros(OnlyNumber(FormatFloat('#0.00', NFSe.Servico.Valores.ValorServicos)), 15) +
                   Poem_Zeros(OnlyNumber(FormatFloat('#0.00', NFSe.Servico.Valores.ValorDeducoes)), 15) +
                   Poem_Zeros(OnlyNumber(NFSe.Servico.ItemListaServico), 5) +
                   sTomador +
                   sInter;

    NFSe.Assinatura := string(TACBrNFSeX(FAOwner).SSL.CalcHash(AnsiString(sAssinatura), dgstSHA1, outBase64, True));
  end;
end;

  • Solution
Postado

Obrigado!

Mas consegui resolver, eu estava fazendo a assinatura sem o certificado, como é feito pelo ISSDigital, mas pra São Paulo é necessário que assine com o certificado que assinou tbm o xml. Segue código que fiz em c# para fazer isso:

 

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

public static class AssinaturaRPS
{
    /// <summary>
    /// Gera a assinatura digital Base64 de uma string de dados, buscando o certificado pelo número de série.
    /// O processo segue o padrão: Hash SHA1 dos dados, assinado com a chave privada RSA (RSA-SHA1).
    /// </summary>
    /// <param name="dadosParaAssinar">A string ASCII que contém as informações do RPS.</param>
    /// <param name="numeroSerieCertificado">O número de série do certificado digital (em formato hexadecimal).</param>
    /// <returns>A assinatura digital em formato Base64.</returns>
    public static string GerarAssinaturaRPS(string dadosParaAssinar, string numeroSerieCertificado)
    {
        X509Certificate2 certificado = null;
        X509Store store = null;

        try
        {
            // 1. Abrir o repositório de certificados (StoreName.My é o repositório pessoal)
            // O StoreLocation.CurrentUser é o local mais comum para certificados de usuário.
            store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

            // 2. Buscar o certificado pelo número de série
            // O número de série deve ser passado em formato hexadecimal (ex: "1234567890ABCDEF").
            X509Certificate2Collection certificadosEncontrados = store.Certificates.Find(
                X509FindType.FindBySerialNumber,
                numeroSerieCertificado,
                validOnly: false // Inclui certificados expirados ou não válidos, ajuste conforme sua necessidade
            );

            if (certificadosEncontrados.Count == 0)
            {
                throw new Exception($"Certificado com número de série '{numeroSerieCertificado}' não encontrado no repositório.");
            }

            // Pega o primeiro certificado encontrado (deve ser único pelo número de série)
            certificado = certificadosEncontrados[0];

            // 3. Obter a chave privada RSA do certificado
            RSA chavePrivada = certificado.GetRSAPrivateKey();

            if (chavePrivada == null)
            {
                throw new InvalidOperationException("O certificado não contém uma chave privada RSA utilizável para assinatura.");
            }

            // 4. Converter a cadeia de caracteres ASCII para bytes
            byte[] dadosEmBytes = Encoding.ASCII.GetBytes(dadosParaAssinar);

            // 5. Assinar o Hash (SHA1) utilizando RSA-SHA1
            byte[] assinaturaEmBytes = chavePrivada.SignData(
                dadosEmBytes,
                HashAlgorithmName.SHA1,
                RSASignaturePadding.Pkcs1
            );

            // 6. Retornar a assinatura em formato Base64
            return Convert.ToBase64String(assinaturaEmBytes);
        }
        catch (Exception ex)
        {
            throw new Exception($"Ocorreu um erro no processo de assinatura: {ex.Message}");
        }
        finally
        {
            // Fechar o repositório de certificados
            if (store != null)
            {
                store.Close();
            }
        }
    }
}

// --- Exemplo de Uso ---
public class ExemploUso
{
    public static void Main()
    {
        // A string que tem que assinar
        string rpsString = "000043090030RPSNF00010101410220251126FNS00000000067991100000000000000006491202470008000144";

        // Substitua pelo número de série do seu certificado (geralmente em formato hexadecimal)
        string seuNumeroDeSerie = "SEUNUMERODESERIEAQUI"; 

        try
        {
            string assinaturaBase64 = AssinaturaRPS.GerarAssinaturaRPS(rpsString, seuNumeroDeSerie);

            Console.WriteLine("--- Resultado da Assinatura Digital ---");
            Console.WriteLine($"String Assinada: {rpsString}");
            Console.WriteLine($"Assinatura (Base64): {assinaturaBase64}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Ocorreu um erro: {ex.Message}");
        }
    }
}
 

Postado

OLa @Alexandre Jansen, sera que voce pode me dar uma luz com seu codigo? Cara, eu consigo fazer o teste no modo SINCRONO, porem ao tentar faze a mesma operacao no modo ASSINCRONO, recebo o Erro 1102 Mensagem XML de Pedido do serviço sem conteúdo. Na imagem abaixo , do lado direito listei os itens que sao diferentes (o XML dos dois sao iguais, de acordo com o manual, pelo menos foi o que entendi).

Comparativoo.jpg

Postado

Ola @Alexandre Jansen , no meu caso nao é do ACBR, eu criei um programa em C# especifico para isso, como vi que voce postou um trecho de codigo C#, caso voce tenha tido sucesso de enviar um loteRPS no modo ASSINCRONO na versao 2.0 e puder me dar uma luz, talvez nos nomes das tags, header ou outra particularidade vai ser de muita ajuda. Grato

  • 2 semanas depois ...
  • Consultores
Postado
Em 09/12/2025 at 18:44, NelsonM disse:

Ola @Alexandre Jansen , no meu caso nao é do ACBR, eu criei um programa em C# especifico para isso, como vi que voce postou um trecho de codigo C#, caso voce tenha tido sucesso de enviar um loteRPS no modo ASSINCRONO na versao 2.0 e puder me dar uma luz, talvez nos nomes das tags, header ou outra particularidade vai ser de muita ajuda. Grato

acho que se não está a falar do componente ACBrNFSeX o mais acertivo seria o subforum https://www.projetoacbr.com.br/forum/forum/65-dúvidas-não-relacionadas-ao-acbr/

 

Consultora ACBr Pro

Juliomar Marchetti

Ajude o Projeto ACBr crescer - Seja Pro

discord: juliomar
telegram: juliomar
e-mail: [email protected]
http://www.juliomarmarchetti.com.br

 

MVP_NewLogo_100x100_Transparent-02.png
Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

  • 1 mês depois ...
  • Este tópico foi criado há 137 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...