Usuário com melhor resposta
Erro ao usar um certificado instalado ou exportado do Windows

Pergunta
-
Saudações a todos.
Estou com problemas para utilizar um certificado digital (eCPF) para assinar documentos PDF.
Aparentemente uma vez que o certificado (arquivo pfx fornecido pela certificadora) é instalado no Windows ele deixa de ser utilizavel.
Escrevi uma aplicação para assinar os arquivos PDF gerados pelo sistema da empresa, que funciona lendo um arquivo de certificado (.pfx) e tutilizando o certificado para assinar o documento gerado.
Tudo muito bonitinho, SE, o arquivo pfx for o arquivo original (repito, fornecido pela certificadora), quando o arquivo é exportado do Windows não funciona, da erro de validação.
Então quando um cliente não tem mais o arquivo original não é possivel assinar os documentos.
Ok, etntão vamos assinar os documentos lendo o certificado diretamente do storage de certificados do windows e esta tudo resolvido, né ?
Não ! Quando um certificado instalado é usado para assinar (estou usando a API do .NET com o C#) o sistema gera uma excessão com a seguinte mensagem:
'Chave inválida para uso no estado especificado'
Então recorro aos senhores grandes conhecedores desta grande "caixa preta" chamada Windows na tentativa de elucidar os mistérios envolvidos.
Que "estado" ? A assinatura digital não serve para assinar ?.
Desde já agradeço qualquer ajuda ou pista, pois não tenho idéia de onde definir o tal "estado" indicado na mensagem.
Informações complementares para a boa alma que se imiscuir nesta aventura:
1 - Os certificados foram instalados no windows com a opção "Permitir a exportação da Chave Privada" ativa.
2 - Nas tentativa de exportação para pfx, todas as combinações de opção (disponiveis na guia de exportação) foram testadas para o certificado do assinante.
(selecionando o certificado do assinante e clicando em Exportar no gerenciador de certificados do windows)
3 - Caso ajude, segue também o código da aplicação que assina usando um certificado instalado, o erro ocorre no momento da geração da PK na linha destacada:
teste.cs:using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.IO; using System.Windows.Forms; using System.Security.Permissions; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using iTextSharp.text.pdf; using iTextSharp.text.xml.xmp; using iTextSharp.text.pdf.security; using iTextSharp.text; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Asn1.X509; using BcX509 = Org.BouncyCastle.X509; ..... //Open certificate collection X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; X509Certificate2Collection findCollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, true); //Create a collection of certificates in a windows form object log("Selecionar certificado..."); X509Certificate2Collection selectCollection = X509Certificate2UI.SelectFromCollection(findCollection , "Selecionar Certificado para Assinatura" , "Selecione um certificado qualquer na lista abaixo para obter informações do certificado." , X509SelectionFlag.MultiSelection); if (openDlg.ShowDialog() == DialogResult.OK) { AssinaPDF(openDlg.FileName, selectCollection[0]); } ..... private void AssinaPDF(string aFileName, X509Certificate2 cert) { PdfReader reader = new PdfReader(aFileName); //Activate MultiSignatures PdfStamper st = PdfStamper.CreateSignature(reader, new FileStream(aFileName+".assinado.pdf", FileMode.Create, FileAccess.Write), '\0', null, true); PdfSignatureAppearance sap = st.SignatureAppearance; sap.Acro6Layers = true; sap.Reason = "Razao - Teste"; sap.Contact = "Contato Fulano de Tal"; sap.Location = "Aqui"; // iTextSharp needs this cert as a BouncyCastle X509 object; this converts it. BcX509.X509Certificate bcCert = DotNetUtilities.FromX509Certificate(cert); var chain = new List<BcX509.X509Certificate> { bcCert }; X509Certificate2 signatureCert = new X509Certificate2(cert); // ####### Esta linha gera uma excessão com a mensagem 'Chave inválida para uso no estado especificado' ######## var pk = DotNetUtilities.GetKeyPair(signatureCert.PrivateKey).Private; IExternalSignature es = new PrivateKeySignature(pk, "SHA-256"); MakeSignature.SignDetached(sap, es, chain, null, null, null, 0, CryptoStandard.CMS); st.Close(); }
- Movido Thales F Quintas quinta-feira, 26 de maio de 2016 14:13
Respostas
-
Resolvido.
O certificado deve ser instalado no repositório do "Usuário Atual".
- Marcado como Resposta -Alexandre P. Trindade domingo, 29 de maio de 2016 15:33