Validar assinaturas - PKI Express
O PKI Express abre um arquivo assinado no seu servidor, lista os signatários e, quando solicitado, valida cada assinatura:
assinaturas em PDF (PAdES), arquivos CMS/CAdES (.p7s) e assinaturas XML.
O PKI Express acrescentou os exploradores de PAdES e CAdES na 1.3.0 e o de XML na 1.25.0.
O código é PHP, dos samples do PKI Suite, a única linguagem com samples para os três
formatos; ele usa o lacuna/pki-express (1.17.0).
Fluxo
- Crie o explorador do formato:
PadesSignatureExplorer,CadesSignatureExplorerouXmlSignatureExplorer. - Aplique as configurações de confiança (veja Quais certificados são confiáveis).
- Defina o arquivo assinado e
validate = true; sem isso, o explorador só inspeciona as assinaturas. - Chame
open(), que executa o comandoopen-pades,open-cadesouopen-xmldo PKI Express e devolve os signatários. - Leia o certificado, a data da assinatura e o
validationResultsde cada signatário.
Assinaturas em PDF (PAdES)
$sigExplorer = new PadesSignatureExplorer();
Util::setPkiDefaults($sigExplorer);
$sigExplorer->setSignatureFile(StorageMock::getDataPath($fileId));
$sigExplorer->validate = true;
$signature = $sigExplorer->open();
Assinaturas CAdES
$sigExplorer = new CadesSignatureExplorer();
Util::setPkiDefaults($sigExplorer);
$sigExplorer->setSignatureFile(StorageMock::getDataPath($fileId));
$sigExplorer->validate = true;
$signature = $sigExplorer->open();
Para obter também o conteúdo assinado, defina o caminho em que o PKI Express o grava, com setExtractContentPath; os samples em Java,
Node.js e Python fazem isso e verificam hasEncapsulatedContent antes de oferecer o arquivo:
CadesSignatureExplorer sigExplorer = new CadesSignatureExplorer();
Util.setPkiDefaults(sigExplorer);
sigExplorer.setSignatureFile(StorageMock.getDataPath(signatureFile));
sigExplorer.setValidate(true);
String outputFile = StorageMock.generateFileId("pdf");
sigExplorer.setExtractContentPath(StorageMock.getDataPath(outputFile));
CadesSignature signature = sigExplorer.open();
- Os samples gravam o conteúdo como PDF, qualquer que seja o tipo dele.
- Para uma assinatura destacada (detached), informe os dados assinados com
setDataFileFromPath(Java:setDataFile). TODO(docs): nenhum sample mostra uma assinatura CAdES destacada.
Assinaturas XML
open() devolve um XmlSignature cujos signers são as assinaturas do documento. O explorador em PHP exige o PKI Express 1.25.1 ou
posterior; as bibliotecas Node.js e Python não têm explorador de XML, e a biblioteca Java tem um na 1.23.1, mas não na 1.20.0.
$sigExplorer = new XmlSignatureExplorer();
Util::setPkiDefaults($sigExplorer);
$sigExplorer->setSignatureFile(StorageMock::getDataPath($fileId));
$sigExplorer->validate = true;
$signatures = $sigExplorer->open()->signers;
Cada signatário XML também tem um type e o signedElement (localName, namespaceUri).
Quais certificados são confiáveis
Por padrão, o PKI Express só confia em certificados emitidos na ICP-Brasil. A função auxiliar dos samples acrescenta as raízes listadas na configuração deles e, para desenvolvimento, a raiz de teste da Lacuna, que aceita os certificados de teste:
$trustedRoots = $config['pkiExpress']['trustedRoots'];
foreach ($trustedRoots as $root) {
$operator->addTrustedRoot(StorageMock::getResourcePath($root));
}
$operator->trustLacunaTestRoot = $config['trustLacunaTestRoot'];
- Veja "Confiando em certificados que não sejam da ICP-Brasil" para Node.js, Java, PHP, Python e Ruby.
- O PKI Express não tem contexto de segurança, ao contrário do Rest PKI: nenhuma das bibliotecas cliente dele tem um.
- A biblioteca Java também pode confiar só na ICP-Brasil (
setTrustOnlyICPBrasil) ou só nas raízes confiáveis do sistema operacional (setTrustOnlySystem).
Políticas de validação
No PAdES, o PKI Express 1.20.0 e posteriores aceitam uma política de validação: pades, pades-with-cert-protection, pki-brazil,
pki-brazil-with-cert-protection ou adobe-reader. Defina-a com validationPolicy (PHP) ou setPolicy (Java), usando
StandardSignaturePoliciesForValidation.
- As bibliotecas Node.js e Python não têm política de validação nos exploradores. A propriedade
signaturePolicydo Node.js só vale na assinatura. - O explorador de XML do Java 1.23.1 recebe um
XmlPoliciesForValidation. - Desde o PKI Express 1.23.0,
trustUncertifiedSigningTime(PHP) ousetTrustUncertifiedSigningTime(Java) aceita como referência de data a data da assinatura declarada pelo signatário.
Ler os resultados
- Uma assinatura PAdES ou CAdES tem
signers; cada um tem o seucertificate,signingTime,messageDigest,signaturePolicy,timestampsevalidationResults. Um signatário PAdES também temisDocumentTimestampesignatureFieldName. validationResultstemisValid(),hasErrors(),hasWarnings()egetSummary(), e vira um texto que lista todas as verificações.- O certificado tem
subjectName,emailAddress,issuerName,serialNumber, as datas de validade e, em certificados ICP-Brasil,pkiBrazil(certificateType,cpf,cnpj,responsavel,companyName,dateOfBirth, RG e OAB).
A página do sample mostra cada signatário com um selo "valid" ou "invalid" a partir de isValid(), a data da assinatura, o resumo da
mensagem (message digest), a política, os campos ICP-Brasil e o texto completo dos resultados da validação.
- O código de retorno 14 (
ValidationFailed) do PKI Express e os erros de validação estão nos códigos de retorno. - TODO(docs): se o
open-*com--validatefalha com o código 14 para uma assinatura inválida ou devolve os resultados com erros (os samples leemisValid()por signatário).