Guia de Implementação da SES GO - Segurança
0.0.2 - draft
Guia de Implementação da SES GO - Segurança - Local Development build (v0.0.2) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
A assinatura digital é fundamental para a segurança, mas precisa ser validada. O processo de validação permite confirmar que a informação não foi alterada após a assinatura, identificar inequivocamente o autor e garantir que o responsável não pode negar sua participação.
Validar uma assinatura digital avançada produzida conforme a política, garantindo a integridade, autoria, autenticidade, não-repúdio e validade da cadeia de certificados, verificando também sua revogação por CRL ou OCSP.
Este processo de validação é compatível com assinaturas criadas conforme o caso de uso de criação e utiliza os mesmos códigos de situações excepcionais padronizados.
Sequência em base64 (padrão FHIR) contendo a string da JWS JSON Serialization completa (RFC 7515 seção 3.2). Este é exatamente o valor produzido pelo caso de uso criar assinatura e armazenado em Signature.data.
Timestamp de referência: inteiro Unix UTC (segundos) usado para TODAS as checagens temporais. Intervalo aceito (inclusivo): 1751328000 (2025-07-01T00:00:00Z) a 4102444800 (2100-01-01T00:00:00Z). A diferença entre o relógio local e este valor não deve exceder ±300s.
Política de assinatura (URI versionada): usada para conferir suporte e requisitos.
(Opcional) Bundle original: necessário apenas se for executar a verificação de integridade opcional.
Nota
Itens 1–4 são obrigatórios. Itens 5–6 somente quando habilitada a verificação de integridade do conteúdo. Qualquer ausência ou valor fora de faixa em itens obrigatórios resulta em OperationOutcome. Todas as validações são realizadas durante o processo.
Resultado da validação, indicativo de sucesso ou rejeição (invalidação), em formato OperationOutcome, detalhando os motivos de eventual invalidação. Em caso de rejeição, implementações devem utilizar o perfil resultado para Assinatura Digital e os códigos padronizados do CodeSystem de Situações Excepcionais para garantir consistência e interoperabilidade.
Ao longo da validação podem ocorrer condições de rejeição; a ocorrência de qualquer uma interrompe a validação. Cada condição de rejeição resulta em uma instância de OperationOutcome com um código específico.
CONFIG.TRUST-STORE-EMPTY.FORMAT.BASE64-INVALID ou CONFIG.INVALID-PARAMETER (se não hex de 64).CONFIG.CERT-MIN-DATE-INVALID.CONFIG.CERT-MIN-DATE-OUT-OF-RANGE.CONFIG.TIMEOUT-OUT-OF-RANGE.CONFIG.TTL-OUT-OF-RANGE.CONFIG.INVALID-PARAMETER.CONFIG.INVALID-PARAMETER.CONFIG.INVALID-PARAMETER.CONFIG.INVALID-PARAMETER.payload (obrigatória)signatures como array (obrigatória)signatures[0] contém as propriedades protected e signature (obrigatórias)signatures[0].header, então a entrada contém evidências para LTV).alg, x5c, sigPId e opcionalmente iatrRefs e opcionalmente sigTstFORMAT.JWS-MALFORMED especificando o problema detectado.2.1 Validação do Protected Header:
signatures[0].protected (base64Url) para obter o objeto JSON correspondente.RS256 ou ES256 (únicos algoritmos suportados).VALIDATION.UNSUPPORTED-ALGORITHM.Para ES256: após decodificação da assinatura (ver 4.2), confirme que o comprimento decodificado é 64 bytes (r |
s); se não for, VALIDATION.SIGNATURE-VERIFICATION-FAILED. |
CERT.INVALID-FORMAT.id com URI da política.POLICY.VERSION-UNSUPPORTED.iat), confirme que é um timestamp Unix UTC válido.TEMPORAL.IAT-INVALID.2.2 Validação do Unprotected Header:
signatures[0].header (objeto JSON não codificado).ocspRefs e/ou crlRefs conforme disponibilidade.digestAlg e digestValue.digestAlg é "http://www.w3.org/2001/04/xmlenc#sha512".digestValue são hashes SHA-512 válidos (88 caracteres base64).digestValue dentro de seu array e ausência de duplicação cruzada entre ocspRefs e crlRefs.VALIDATION.LTV-EVIDENCE-INVALID.tsa), confirme que contém token TSA válido em base64.TSA.INVALID-TOKEN.2.3 Determinação da Estratégia de Timestamp:
protected.iat presente e unprotected.sigTst ausente: estratégia iatprotected.iat ausente e unprotected.sigTst presente: estratégia tsaVALIDATION.TIMESTAMP-STRATEGY-INVALID3.1 Extração e decodificação:
x5c do protected header.FORMAT.BASE64-INVALID.CERT.INVALID-FORMAT.3.2 Verificação da estrutura da cadeia:
CERT.CHAIN-INCOMPLETE.3.3 Validação da raiz ICP-Brasil:
CERT.NOT-ICP-BRASIL.3.4 Verificação de elegibilidade ICP-Brasil:
2.16.76.1.CERT.NOT-ICP-BRASIL.3.5 Verificação da data mínima de emissão (issue date):
notBefore do certificado folha.notBefore < data mínima → CERT.ISSUE-DATE-TOO-OLD.3.6 Validação temporal da cadeia:
iat, o valor iat deve também estar dentro do mesmo intervalo; divergências serão tratadas em 6.1.notBefore ≤ timestamp ≤ notAfterCERT.EXPIREDCERT.NOT-YET-VALIDnotAfter - timestamp) < nearExpiryThresholdDays * 86400 → adicionar warning CERT.NEAR-EXPIRY (não interrompe processo)3.7 Validação criptográfica da hierarquia:
i de 0 a n-2:
i usando a chave pública do certificado i+1subject do certificado i+1 = issuer do certificado iCERT.CHAIN-VALIDATION-FAILED3.8 Verificação de algoritmos e tamanhos de chave:
CERT.WEAK-KEY ou CERT.UNSUPPORTED-ALGORITHM4.1 Construção da string de assinatura (signing input):
signatures[0].protected.payload.protected_header.payload.4.2 Preparação para verificação:
signatures[0].signature de base64Url para obter os bytes da assinatura.x5c).4.3 Verificação criptográfica:
alg do protected header:
RS256: Use RSA com SHA-256 (RSASSA-PKCS1-v1_5)ES256: Use ECDSA com SHA-256 e curva P-256protected_header.payloadsignatures[0].signatureVALIDATION.SIGNATURE-VERIFICATION-FAILED.4.4 Verificações de segurança adicionais:
alg.CRYPTO.TIMING-ATTACK-DETECTED.5.1 Estratégia de validação:
rRefs (recomendado para Long Term Validation)REVOCATION.CACHE-EXPIRED).fetchedAt, nextUpdate (se fornecido) e calcular expiresAt = min(fetchedAt + TTL, nextUpdate).referenceTimestamp > expiresAt e renovação falhar → REVOCATION.CACHE-EXPIRED (erro em strict, warning em soft-fail/warn).5.2 Validação usando evidências LTV (rRefs):
5.2.1 Evidências OCSP (ocspRefs):
rRefs.ocspRefs:
digestAlg = "http://www.w3.org/2001/04/xmlenc#sha512"digestValue é hash SHA-512 válido (88 caracteres base64)VALIDATION.LTV-EVIDENCE-INVALID5.2.2 Evidências CRL (crlRefs):
rRefs.crlRefs:
5.3 Consulta online de revogação (quando necessário):
CERT.REVOKEDREVOCATION.OCSP-UNAVAILABLE ou REVOCATION.CRL-UNAVAILABLECERT.REVOKED; treat-as-warning → warning + continuar.REVOCATION.OCSP-UNAVAILABLE, REVOCATION.CRL-UNAVAILABLE, REVOCATION.CACHE-EXPIRED e status 'unknown' são sempre warnings (não erros), exceto se combinado com evidência explícita de revogação.REVOCATION.CACHE-EXPIRED (warning em soft-fail/warn; erro em strict).5.4 Interpretação de resultados:
Nota sobre evidências LTV:
As evidências em rRefs permitem validação offline e futura, mas contêm apenas hashes das respostas OCSP/CRL originais. Para validação completa, pode ser necessário acesso aos dados originais ou consulta online conforme política de segurança.
6.1 Validação por estratégia de timestamp:
Estratégia iat (timestamp auto-declarado):
iat do protected header.iat ≥ notBefore do certificado signatárioiat ≤ notAfter do certificado signatárioiat ≤ timestamp de referência (entrada 4)iat e timestamp de referência > 300s, emitir warning TEMPORAL.CLOCK-SKEW-DETECTED (se ainda dentro da validade) ou erro se quebra limites de validade.TEMPORAL.IAT-OUT-OF-CERT-PERIODEstratégia tsa (timestamp por TSA):
sigTst no unprotected header.TSA.UNAVAILABLE (ou aplicar política revocationPolicy se alinhado a fallback temporal).TSA.INVALID-RESPONSETSA.VALIDATION-FAILEDTSA.UNAVAILABLE| Avalie skew: se | tsaTimestamp - timestamp de referência | > 300s: emitir TEMPORAL.CLOCK-SKEW-DETECTED (warning) se ainda dentro da validade, caso contrário erro apropriado (ex.: TEMPORAL.TSA-TIMESTAMP-OUT-OF-BOUNDS). |
6.2 Validação da política de assinatura:
sigPId.id no protected header.POLICY.VERSION-UNSUPPORTEDVALIDATION.POLICY-COMPLIANCE-FAILED6.3 Verificações de segurança adicionais:
tsa, valide que o timestamp TSA está consistente com as evidências LTVTEMPORAL.SIGNATURE-TOO-OLD.7.1 Sucesso:
issue.severity = informationissue.code = informationalissue.details.coding usando código VALIDATION.SUCCESS do CodeSystem de situações excepcionaisissue.details.text = "Assinatura digital validada com sucesso"issue.diagnostics com detalhes da validação (algoritmo, política, estratégia de timestamp)7.2 Tabela de códigos de retorno (sucesso e condições de rejeição): Todos os códigos retornáveis neste processo (sucesso e condições de rejeição) em ordem alfabética. A severidade efetiva é definida no CodeSystem; aqui lista-se o significado textual. O termo "condição de rejeição" neste documento significa que a assinatura é considerada inválida, não implicando defeito interno no software validador.
| Código | Descrição |
|---|---|
| CERT.CHAIN-VALIDATION-FAILED | Cadeia de certificados inválida |
| CERT.EXPIRED | Certificado expirado na cadeia |
| CERT.INVALID-FORMAT | Array x5c malformado ou certificados inválidos |
| CERT.NOT-ICP-BRASIL | Certificado não elegível ICP-Brasil |
| CERT.REVOKED | Certificado revogado detectado |
| CERT.WEAK-KEY | Tamanho de chave insuficiente |
| FORMAT.BASE64-INVALID | Dados base64 inválidos em componentes JWS |
| FORMAT.JWS-MALFORMED | Estrutura JWS JSON não conforme RFC 7515 |
| POLICY.VERSION-UNSUPPORTED | Versão da política não implementada |
| REVOCATION.CACHE-EXPIRED | Entrada de cache de revogação expirada e não renovada |
| REVOCATION.CRL-UNAVAILABLE | Serviço CRL indisponível |
| REVOCATION.OCSP-UNAVAILABLE | Serviço OCSP indisponível |
| TEMPORAL.IAT-OUT-OF-CERT-PERIOD | Timestamp iat fora da validade do certificado |
| TSA.VALIDATION-FAILED | Falha na validação do token TSA |
| VALIDATION.LTV-EVIDENCE-INVALID | Evidências LTV inconsistentes |
| VALIDATION.POLICY-COMPLIANCE-FAILED | Assinatura não conforme com política |
| VALIDATION.SIGNATURE-VERIFICATION-FAILED | Falha na verificação da assinatura digital |
| VALIDATION.SUCCESS | Assinatura digital validada com sucesso |
| VALIDATION.UNSUPPORTED-ALGORITHM | Algoritmo de assinatura não suportado |
7.3 Formato do OperationOutcome:
issue.diagnostics quando apropriadoissue.location quando possívelissueEsta seção é opcional e aplicável apenas quando o validador tem acesso ao conteúdo original (Bundle e Provenance) que foi assinado e deseja verificar se não foi alterado.
Pré-requisitos:
Processo de verificação:
1. Preparação das instâncias:
Provenance.target, crie uma cópiaid, meta.versionId, meta.lastUpdated, meta.source e meta.tagmeta.profile e meta.security (estes elementos fazem parte da assinatura)2. Canonicalização:
Provenance.target3. Concatenação e hash:
Provenance.target4. Codificação e comparação:
payload extraído do JWS JSON SerializationNota importante: Esta verificação é independente da validação da assinatura digital. Uma assinatura pode ser criptograficamente válida mesmo se o conteúdo original não estiver disponível ou tiver sido alterado após a assinatura.
Segurança na implementação:
SECURITY.BUNDLE-SIZE-LIMIT-EXCEEDED; se tamanho serializado > maxBundleBytes → SECURITY.BUNDLE-MEMORY-LIMIT-EXCEEDED; se tempo de processamento exceder bundleVerifyTimeout → SECURITY.BUNDLE-TIMEOUT-EXCEEDED.