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}");
}
}
}
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.