Jump to content

Labreu

New Member
  • Posts

    10
  • Joined

  • Last visited

Labreu's Achievements

boolean user

boolean user (2/5)

3

Reputation

  1. Boas. Se alguém tiver interesser, criei uma demo online: https://github.com/luisabreu/AmaCmdSigning
  2. Boas pessoal! FInalmente, está a funcionar como deve: https://stackoverflow.com/questions/66671008/itext7-deferred-signing-not-producing-a-valid-signed-pdf?noredirect=1#comment117931277_66671008 btw, parece q a assinatura inicial (so com o CMS PdfPCKS7) so e adequado em algumas situacoes. Nos comentarios, o mkl explica a diferenca entre as duas formas de assinar...Agora, ver como faco o timestamp disto! que aventura...
  3. Boas pessoal. O código que tenho aqui está produzir mm resultado. O aviso no pdf faz sentido (acho) pq os certificados enviados não pertencem a uma chain fidedigna. No meu caso, ainda estou a tentar perceber o que é que o comentário que tive num post do stackoverflow quer dizer: Basicamente, e de acordo com este user, a forma de criar o container para injetar a assinatura da AMA está errada. Eu já mudei o código para tentar seguir as ideias dele, mas a verdade é que nao esta a funcionar. Já agora, e por curiosidade, o código que estou a usar no método Sign do IExternalSignatureContainer que preparar o hash passou a ser: public override byte[] Sign(Stream data) { // create PCKS7 for getting byte attributes var sgn = new PdfPKCS7(null, _certificates.ToArray(), DigestAlgorithms.SHA256, false); DocumentDigest = DigestAlgorithms.Digest(data, DigestAlgorithms.SHA256); var docBytesHash = sgn.GetAuthenticatedAttributeBytes(DocumentDigest, PdfSigner.CryptoStandard.CMS, null, null); var totalHash = new byte[_sha256SigPrefix.Length + docBytesHash.Length]; _sha256SigPrefix.CopyTo(totalHash, 0); docBytesHash.CopyTo(totalHash, _sha256SigPrefix.Length); DataToSend = totalHash; return new byte[0]; } Como ele diz que depois o GetEncodedPKCS7 tem de ser chamado com os mesmos parametros que o GetAuthenticatedAttributeBytes, enstao esou a guarda o hash e o digest originais. Depois, alterei ainda o Sign do outro IExternalSignatureContainer que é usado para injetar a assinatura recebida da AMA para: public byte[] Sign(Stream data) { var sgn = new PdfPKCS7(null, _certificates.ToArray(), DigestAlgorithms.SHA256, false); sgn.SetExternalDigest(_signature, null, "RSA"); var encodedSig = sgn.GetEncodedPKCS7(_documentHash, PdfSigner.CryptoStandard.CMS, null, null, null); return encodedSig; } Infelizmente, os resultados sao negativos 😞
  4. @Morfas3Sim, essa parte está ok. A questão aqui é outra: a forma como geramoso CMS para colocar a assinatura não está correta (na verdade, os mues conhecimentos limitados na área não me permitem aferir bem qual a solução correta, mas parece q apesar de o adobe mostrar corretamente o certificado, a assinatura como está implementada não é totalmente correta...)
  5. Infelizmente, só consegui responder hoje (limitação número de posts?)... Nesta altura, produzo o mm resultado "visual" que o @reznor. A questão é que parece que a assinatura efetuada não está 100% correta pq ainda deveria incluir os "atributos" do documento (ver resposta e comentários desta entrada)...
  6. Ok, progresso...afinal n posso gerar o hash a partir do ficheiro com assinatura vazia, mas sim so dos bytes do ficheiro...aha.....agora ver a parte do certificado.
  7. O teu está ok! da erro pq a chain de certificados nao e confiavel (presumo q se passares producao a coisa funciona sem erros). No meu caso, estou a gerar mal o hash do documento, mas ainda ainda nao percebi o erro....
  8. Damn...sim, já está melhor, mas ainda devo ter um erro aqui no cálculo do hash. Agora já mostra info assinatura mas dá o erro tipico do ficheiro modificado depois da assinatura...
  9. Sim, penso que estou a fazer corretamente isso. Basicamente, estou a fazer o seguinte (C#): public byte[] GetDocHashFromPreparedDocToSign(string pathToOriginalPdf, string pathToPreparedToBeSignedPdf, List<X509Certificate> certificates) { var pdfSigner = new PdfSigner(new PdfReader(pathToOriginalPdf), new FileStream(pathToPreparedToBeSignedPdf, FileMode.Create), new StampingProperties()); pdfSigner.SetFieldName(_signatureFieldname); var appearance = pdfSigner.GetSignatureAppearance(); appearance.SetPageRect(new Rectangle(144, 144, 200, 100)) .SetPageNumber(1) .SetCertificate(certificates[0]); var container = new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite, PdfName.Adbe_pkcs7_detached); pdfSigner.SignExternalContainer(container, 8192); byte[] sha256SigPrefix = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; // get hash from pdf with reserved space and preprending with specified using var stream = File.OpenRead(pathToPreparedToBeSignedPdf); var data = DigestAlgorithms.Digest(stream, DigestAlgorithms.SHA256); var totalHash = new byte[sha256SigPrefix.Length + data.Length]; sha256SigPrefix.CopyTo(totalHash, 0); data.CopyTo(totalHash, sha256SigPrefix.Length); return totalHash; } O resultado deste metodo e passado para o servico da CMD: var pdfManager = new PdfManager(); var pathToSigned = "c:\\temp\\doc1.pdf"; var docHash = pdfManager.GetDocHashFromPreparedDocToSign(pathDocPdf, pathToSigned, certificates); var signReq = new SignRequest { ApplicationId = applicationId, DocName = "Doc1.pdf", Hash = docHash, Pin = pinCmdBase64, UserId = userIdBase64 }; SignStatus resScmdSign = await client.SCMDSignAsync(signReq); O resultado devolvido esta ok (200), pelo que me limito a chamar o ValidateOptAsync: var resValidacaoPin = await client.ValidateOtpAsync(codeBase64, resScmdSign.ProcessId, applicationId); if(resValidacaoPin.Status.Code == "200") { var pathToSignedWithSiognature = "c:\\temp\\doc1_signed.pdf"; // valid signature, replace temporary with new one pdfManager.SignPreparedToBeSignedDoc(pathToSigned, pathToSignedWithSiognature, resValidacaoPin.Signature); } E já agora, o método SignPreparedToBeSignedDoc: public void SignPreparedToBeSignedDoc(string pathToPreparedToBeSignedPdf, string pathToSignedFile, byte[] signature) { var document = new PdfDocument(new PdfReader(pathToPreparedToBeSignedPdf)); using var writer = new FileStream(pathToSignedFile, FileMode.Create); var container = new ExternalInjectingSignatureContainer(signature); PdfSigner.SignDeferred(document, _signatureFieldname, writer, container); } internal class ExternalInjectingSignatureContainer : IExternalSignatureContainer { private readonly byte[] _signature; public ExternalInjectingSignatureContainer(byte[] signature) { _signature = signature; } public byte[] Sign(Stream data) => _signature; public void ModifySigningDictionary(PdfDictionary signDic) { } } Edição: Relativamente aos certificados, estou a recuperar a chain devolvida pela AMA e a utilizar o primeiro certificado. O código de recuperação dos certificados é o seguinte: public static List<X509Certificate> ConvertStringToCertificate(string certificate) { byte[] bytes = Encoding.ASCII.GetBytes(certificate); var certs = new X509CertificateParser().ReadCertificates(bytes) .Cast<X509Certificate>() .ToList(); return certs; } Basicamente, faco o SignDeferred e passo o array de bytes devolvido pelo valdateopt da CMD... À primeira vista, parece-me que isto está certo, mas às tantas estou a falhar algo óbvio...
  10. Boas pessoal. Tb estou a tentar implementar a assinatura digital mas estou a ter o mesmo erro na assinatura que o @reznor estava a ter. Na prática, esotu obter certificado sem pin, recuperar a chain de certificados (lista) através do bouncy castle e a utilizar a mm estratégia que estão usar aqui... Acho eu... Mas está mm a me faltar algo simples... @reznor alguma dica para passar da imagem 1 a 2? Já agora, estavas a ter o ber encoding error? Obrigado.
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.