Carimbo do Tempo de ACT via API: PAdES-B-T, CAdES-T e Como Conferir o Token
Toda assinatura feita pela SignDocs registra a hora em que aconteceu. A pergunta que aparece em avaliações técnicas e em contratos mais exigentes é outra: quem atesta essa hora? Por padrão, é o relógio dos servidores da plataforma, amarrado ao hash do documento e à trilha de auditoria. Para as assinaturas com certificado digital ICP-Brasil, existe uma segunda opção: o carimbo do tempo de uma Autoridade de Carimbo do Tempo (ACT), emitido por terceiro credenciado e embutido na própria assinatura.
Este guia é técnico. Mostra o que o carimbo acrescenta à estrutura da assinatura, como ele é obtido durante o fluxo, onde aparece nas respostas da API e como conferir o token de forma independente, com OpenSSL, sem depender da SignDocs. O conceito geral de carimbo do tempo está em carimbo do tempo na assinatura digital; a anatomia do CMS que o recebe está em PKCS#7/CMS, PAdES e CAdES.
O que o carimbo acrescenta à assinatura
Uma assinatura PAdES ou CAdES é uma estrutura CMS (SignedData). Dentro dela, cada signatário tem um SignerInfo com os atributos assinados (hash do documento, hora declarada pelo assinador, certificado) e o valor da assinatura, calculado com a chave privada do titular. Esse é o nível baseline, B-B.
O carimbo do tempo entra depois, como atributo não assinado id-aa-signatureTimeStampToken (RFC 3161, apêndice A). O token é emitido pela ACT sobre o hash do valor da assinatura, não sobre o documento. A consequência é precisa: o token prova que aquela assinatura, com aqueles bytes, já existia no instante que a ACT registrou. Como é um atributo não assinado, ele pode ser acrescentado sem invalidar a assinatura do titular. Com ele, a assinatura passa a PAdES-B-T (PDF) ou CAdES-T (demais formatos, em .p7s).
| Aspecto | Baseline (B-B) | Com carimbo de ACT (B-T) |
|---|---|---|
| Referência temporal | Hora do servidor SignDocs (signingTime e signedAt), em ISO-8601 UTC |
A mesma hora do servidor, mais o genTime atestado pela ACT |
| Quem atesta a hora | A plataforma, com hash e trilha de auditoria append-only | Uma ACT credenciada na ICP-Brasil, com certificado próprio de carimbo do tempo |
| Onde fica | Atributos assinados e pacote de evidências | Também dentro do SignerInfo, como atributo não assinado |
| Conferência | Verificador público e pacote de evidências | Também com qualquer ferramenta RFC 3161, como openssl ts |
| Tamanho | CMS com a cadeia do signatário | Cerca de 4 KB a mais por assinatura, o tamanho do token |
Nos perfis eletrônicos (aceite, OTP, biometria), a referência temporal é o carimbo de hora do servidor com a trilha de auditoria. O carimbo de ACT é um recurso das assinaturas com certificado digital, porque depende de existir um valor de assinatura ICP-Brasil sobre o qual carimbar.
Como o carimbo é obtido durante o fluxo
A assinatura com certificado na SignDocs tem duas fases: prepare, em que o servidor monta os atributos e devolve o hash a assinar, e complete, em que recebe o valor da assinatura e monta o CMS. O carimbo se encaixa assim:
- No prepare, a decisão é registrada. Se o recurso está habilitado, a solicitação de assinatura é marcada para receber carimbo e o espaço reservado para a assinatura no PDF é ampliado, porque o token não cabe no espaço padrão. A cota de carimbos também é conferida aqui, antes de o signatário digitar o PIN.
- O signatário assina normalmente. Nada muda para ele: o hash a assinar é o mesmo, com ou sem carimbo.
- No complete, a plataforma confere antes de carimbar. O valor de assinatura recebido é verificado contra o certificado informado; uma assinatura que não confere é recusada antes de qualquer pedido à ACT.
- A ACT carimba o valor da assinatura. A plataforma envia uma requisição RFC 3161 com o SHA-256 do valor da assinatura, um nonce aleatório e o pedido de inclusão do certificado da ACT no token. Na resposta, confere que o hash e o nonce batem com o pedido, que a política é de carimbo do tempo ICP-Brasil e que a cadeia do certificado da ACT é válida.
- O token é embutido. Ele entra no
SignerInfocomo atributo não assinado, o CMS é montado e a assinatura fica em B-T.
O carimbo é emitido pela ACT do SERPRO, sob a política de carimbo do tempo ICP-Brasil 2.16.76.1.6.2. A cadeia do certificado do servidor de carimbo do tempo termina na Raiz da ICP-Brasil, como a de qualquer certificado ICP.
Como habilitar
O carimbo de ACT é um recurso opcional, habilitado por contrato no plano sob medida da API, e cada carimbo emitido consome uma unidade de uma cota própria, separada da cota de documentos. A habilitação vale para o tenant inteiro: não existe um campo novo no request. Uma vez ligado, toda assinatura com certificado digital feita pelas suas credenciais recebe o carimbo, seja pela página de assinatura hospedada, seja pelo fluxo de duas fases chamado pelo seu backend.
Onde ver o carimbo nas respostas da API
Os dados do carimbo aparecem em três lugares. O primeiro é a resposta de POST /v1/transactions/{id}/signing/complete, para quem conduz o fluxo de duas fases pelo backend: a resposta traz result.digitalSignature.signatureTimestamp.
| Campo | Significado |
|---|---|
genTime |
Data e hora atestadas pela ACT. signedAt continua sendo a hora do servidor SignDocs; os dois ficam lado a lado. |
tsaName |
Nome distinto do certificado do servidor de carimbo do tempo que emitiu o token. |
serial |
Número de série do carimbo, único por emissão. |
policyOid |
Política de carimbo do tempo ICP-Brasil sob a qual o token foi emitido. |
tokenSha256 |
SHA-256 do token embutido, para conferir que o token que você extrair do arquivo é o mesmo registrado. |
O segundo lugar é o pacote de evidências (.p7m), obtido por GET /v1/transactions/{id}/evidence: o registro da assinatura digital dentro dele traz o mesmo bloco signatureTimestamp, com os cinco campos. Detalhes do pacote em evidence pack .p7m.
O terceiro é a verificação pública, GET /v1/verify/{evidenceId}, que alimenta o verificador. Cada item de steps referente à assinatura com certificado traz signatureTimestamp com genTime, tsaName e policyOid. Esses três campos são públicos por natureza: já estão dentro do próprio arquivo assinado. Veja verificação pública de assinatura via API.
Se o bloco signatureTimestamp não aparece, a assinatura não tem carimbo de ACT: o recurso não estava habilitado no prepare daquele signatário, ou o perfil não é de certificado digital.
Como conferir o carimbo de forma independente
O ponto do carimbo de terceiro é não depender da palavra da plataforma. O token pode ser extraído do arquivo assinado e verificado com ferramentas comuns.
Arquivos .p7s (CAdES-T) com OpenSSL
Para arquivos que não são PDF, o documento assinado é um .p7s baixado por GET /v1/transactions/{id}/download. O roteiro tem quatro passos: localizar o token e o valor da assinatura na estrutura, recortar os dois, inspecionar o token e verificá-lo.
A saída esperada do passo 4 é Verification: OK. Os certificados da Raiz e das ACs intermediárias da ACT ficam no repositório de certificados da ICP-Brasil, mantido pelo ITI; o certificado do próprio servidor de carimbo vem dentro do token. Duas conferências extras fecham o circuito: o sha256sum token.der deve bater com o tokenSha256 da resposta da API, e o Time stamp impresso no passo 3 deve bater com o genTime.
-data assinatura.bin e não o documento? Porque o token foi emitido sobre o valor da assinatura. Passar o documento original faz a verificação falhar por imprint divergente, e isso não indica problema no carimbo. Se o seu arquivo estiver em PEM, converta para DER antes de usar os offsets com dd.
PDFs (PAdES-B-T)
No PDF, o CMS fica dentro do dicionário de assinatura. O caminho prático é o validador: no painel de assinaturas de leitores como o Adobe Acrobat Reader, as propriedades da assinatura indicam que ela inclui um carimbo de data/hora incorporado e mostram a hora atestada pela ACT; o roteiro está em validar assinatura digital no Adobe Reader. O validador do ITI (validar.iti.gov.br) também exibe o carimbo do tempo na assinatura. Para conferir com OpenSSL, extraia o CMS do /Contents com a biblioteca de PDF de sua preferência e siga o roteiro acima.
Tratando falhas: ACT indisponível e cota
O carimbo é falha fechada: num tenant com o recurso habilitado, uma assinatura com certificado não é concluída sem ele. São dois casos a tratar.
| Situação | Resposta | O que fazer |
|---|---|---|
| A ACT não emitiu o carimbo | 503 no complete, com code: "TIMESTAMP_UNAVAILABLE", retryable: true e Retry-After: 30 |
Aguardar e reenviar a mesma rawSignatureBase64 com o mesmo signatureRequestId, sem pedir o PIN de novo, em até 15 minutos após o prepare. Depois disso, refazer o prepare. |
| Cota de carimbos esgotada (diária ou mensal) | 429 já no prepare, com RateLimit-Limit, RateLimit-Remaining: 0, RateLimit-Reset e Retry-After |
Nada a reenviar antes do reset. O signatário é barrado antes de digitar o PIN; acione o time comercial se o volume do contrato ficou curto. |
No 503, a solicitação de assinatura continua pendente: nada se perde e nada é cobrado, porque o carimbo só é contado depois de emitido e verificado. Na página de assinatura hospedada, o signatário vê a mensagem do campo detail e pode tentar de novo. O formato completo dos erros está em códigos de erro e tratamento de falhas.
Testando no sandbox
No sandbox de homologação, o recurso é habilitado sob demanda, com uma cota pequena. Os carimbos emitidos lá são carimbos reais da ACT, não simulações: o token verifica com OpenSSL contra a Raiz ICP-Brasil exatamente como em produção. Por isso vale planejar o teste em vez de rodá-lo a cada build:
- Um teste de ponta a ponta por formato. Um PDF e um arquivo não PDF bastam para validar a extração do bloco
signatureTimestampe o roteiro de verificação. - Teste do 503 com mock. O tratamento de
TIMESTAMP_UNAVAILABLEse testa no seu código, simulando a resposta; não depende de derrubar a ACT. - Envelope com dois signatários. Confirma que cada assinatura recebe o próprio token, com o próprio
genTime.
Para combinar o carimbo com o restante da integração de certificado digital, o ponto de partida é a API de assinatura digital ICP-Brasil; a visão geral dos recursos está em API de assinatura digital.
O que o carimbo não muda
O carimbo de ACT acrescenta uma referência temporal de terceiro; ele não substitui o resto da evidência. A trilha de auditoria, o hash SHA-256 do documento, a cadeia do certificado do signatário e o pacote de evidências continuam sendo gerados da mesma forma. Também não muda o nível de validação de longo prazo: a inclusão de dados de revogação e os níveis LT e LTA entram no dimensionamento do plano sob medida quando o caso exigir.
Se o carimbo é necessário no seu caso é uma decisão do seu negócio: alguns contratos e políticas internas pedem uma referência temporal emitida por terceiro, outros consideram suficiente a hora do servidor com a trilha de auditoria. A API oferece as duas, e o resultado de cada uma é verificável.
Perguntas Frequentes
A API da SignDocs oferece carimbo do tempo de ACT?
Sim, como recurso opcional habilitado por contrato no plano sob medida. Nas assinaturas com certificado digital ICP-Brasil, a plataforma obtém um carimbo RFC 3161 da ACT do SERPRO sobre o valor da assinatura e o embute no próprio CMS, que passa a PAdES-B-T (PDF) ou CAdES-T (.p7s). Cada carimbo consome uma unidade de uma cota própria. Nos perfis eletrônicos, a referência temporal é o carimbo de hora do servidor com a trilha de auditoria.
Preciso mudar meu request para receber o carimbo?
Não. A habilitação vale para o tenant inteiro e não há campo novo no request. Uma vez ligado, toda assinatura com certificado digital feita pelas suas credenciais recebe o carimbo, pela página hospedada ou pelo fluxo de duas fases (signing/prepare e signing/complete). A decisão é tomada no prepare de cada signatário, então ligar o recurso no meio de um envelope vale para os próximos signatários. O hash a assinar é o mesmo, com ou sem carimbo.
Onde vejo os dados do carimbo nas respostas?
Em três lugares: na resposta de POST /v1/transactions/{id}/signing/complete, em result.digitalSignature.signatureTimestamp (genTime, tsaName, serial, policyOid e tokenSha256); no pacote de evidências .p7m, obtido por GET /v1/transactions/{id}/evidence; e na verificação pública GET /v1/verify/{evidenceId}, em steps[].signatureTimestamp, com genTime, tsaName e policyOid. Se o bloco não aparece, a assinatura não tem carimbo de ACT.
Qual a diferença entre genTime e signedAt?
O signedAt é a hora registrada pelo servidor da SignDocs no momento da assinatura, a mesma usada em todos os perfis. O genTime é a hora atestada pela ACT dentro do token RFC 3161. Os dois ficam lado a lado na resposta e no pacote de evidências e podem diferir pelo intervalo entre a montagem da assinatura e a resposta da ACT.
O que fazer quando a API devolve 503 TIMESTAMP_UNAVAILABLE?
Significa que a ACT não emitiu o carimbo e, como o recurso é de falha fechada, a assinatura não foi concluída. A solicitação continua pendente: aguarde o Retry-After (30 segundos) e reenvie a mesma rawSignatureBase64 com o mesmo signatureRequestId, sem pedir o PIN de novo, em até 15 minutos após o prepare. Depois disso, refaça o prepare. Nada é cobrado: o carimbo só é contado depois de emitido e verificado.
Como verifico o carimbo sem depender da SignDocs?
Em um .p7s, localize com openssl asn1parse o atributo id-smime-aa-timeStampToken e o valor da assinatura do mesmo SignerInfo, recorte os dois com dd e rode openssl ts -verify com o token, o valor da assinatura como dado e a cadeia da ICP-Brasil. A saída esperada é Verification: OK. Em PDFs, o painel de assinaturas do leitor e o validador do ITI mostram o carimbo incorporado. O SHA-256 do token deve bater com o tokenSha256 da API.
Teste a assinatura com certificado e o carimbo de ACT no sandbox
Crie credenciais de homologação gratuitas, sem cartão, e valide o fluxo de certificado digital de ponta a ponta. Para habilitar o carimbo de ACT no sandbox ou em produção, fale com o time comercial.
Criar credenciais de homologação Fale com o time comercial