Pular para o conteúdo principal

Representação visual PAdES - Rest PKI Core

A representação visual de uma assinatura PAdES é a sua aparência visível no PDF: um texto, uma imagem ou os dois, desenhados dentro de um retângulo em uma das páginas. Ela é opcional: sem ela, a assinatura é invisível, mas continua válida, e os leitores de PDF a listam no painel de assinaturas.

A representação visual tem três partes: o texto, a imagem e a posição do retângulo na página. Somente a posição é obrigatória.

"visualRepresentation": {
"text": { ... },
"image": { ... },
"position": { ... }
}
dica

A partir daqui descreveremos chamadas ao Rest PKI Core. Certifique-se de ter lido o artigo Primeiros passos para acompanhar.

Onde definir​

A representação visual faz parte das opções de assinatura de PDF, pdfSignatureOptions, no campo visualRepresentation:

APIOnde
Sessões de assinatura: POST {endpoint}/api/signature-sessionspdfSignatureOptions.visualRepresentation, que vale para todos os PDFs assinados na sessão
Sessões de assinatura, documentos predefinidosdocuments[].pdfSignatureOptions.visualRepresentation, para um documento
Assinaturas em duas etapas: POST {endpoint}/api/signaturepdfSignatureOptions.visualRepresentation
Carimbos em PDF: POST {endpoint}/api/pdf/stampvisualRepresentation, no nível principal da requisição. Usa o mesmo modelo descrito aqui, mas as tags do texto não são substituídas: não há signatário, então elas permanecem como foram escritas
observação

Quando um documento predefinido de uma sessão de assinatura tem pdfSignatureOptions próprio, ele substitui por completo o pdfSignatureOptions da sessão: os dois não são combinados, então repita o visualRepresentation no documento. A exceção é convertToPdfA, que o documento herda da sessão (veja Conversão para PDF/A).

As APIs legadas do Rest PKI que o Rest PKI Core ainda atende (veja Migração do Rest PKI) usam o mesmo modelo no campo visualRepresentation da requisição.

Texto​

O objeto text desenha um texto no retângulo:

CampoDescrição
textO texto, que pode ter {{tags}} (veja abaixo) e quebras de linha. Obrigatório sempre que text é enviado: um objeto text sem ele falha
includeSigningTimeQuando true, acrescenta uma linha com o horário da assinatura, formatado com as configurações de data e hora da organização. Padrão: false
fontSizeO tamanho máximo da fonte, em pontos: o texto diminui, quando necessário, para caber no retângulo. Padrão: 12
horizontalAlignLeft (padrão) ou Right
containerA região do retângulo da assinatura onde o texto é desenhado, como um retângulo relativo ao retângulo da assinatura (e não à página). Se omitido, o texto pode usar todo o retângulo da assinatura. O texto é alinhado ao topo da região

Por exemplo, para deixar uma margem de 0,2 em volta do texto:

"text": {
"text": "Assinado digitalmente por {{name}}",
"fontSize": 9,
"includeSigningTime": true,
"horizontalAlign": "Left",
"container": { "left": 0.2, "top": 0.2, "right": 0.2, "bottom": 0.2 }
}

Tags​

Em uma assinatura, as tags em text são substituídas por dados do certificado do signatário (em um carimbo, elas permanecem como foram escritas). Elas diferenciam maiúsculas de minúsculas, e uma tag desconhecida permanece no texto como foi escrita. As mais usadas:

TagValor
{{name}}O nome completo do signatário
{{national_id}}O número de identidade nacional do signatário (em certificados ICP-Brasil, o CPF do titular)
{{email}}O endereço de e-mail do signatário
{{issuer_cn}}O nome comum (CN) do emissor do certificado
{{br_cpf_formatted}}O CPF do titular, formatado como 000.000.000-00 (certificados ICP-Brasil)
{{br_cpf_masked}}O CPF do titular, mascarado (certificados ICP-Brasil)

Veja a lista completa de tags, que são as mesmas do Rest PKI.

Imagem​

O objeto image desenha uma imagem no retângulo, atrás do texto:

CampoDescrição
resourceA imagem, como url (um link de onde o servidor baixa a imagem; a imagem fica em cache por cerca de 5 minutos) ou content (os bytes em Base64). Um dos dois é obrigatório, e content prevalece quando os dois são enviados
opacityDe 0 a 100. Padrão: 100
horizontalAlignLeft, Center (padrão) ou Right
verticalAlignTop, Center (padrão) ou Bottom

A imagem é redimensionada para caber no retângulo, mantendo a proporção. Quando o retângulo é mais largo que a imagem redimensionada, quem a posiciona é horizontalAlign; caso contrário, é verticalAlign.

"image": {
"resource": { "url": "https://example.com/seal.png" },
"opacity": 40,
"horizontalAlign": "Right",
"verticalAlign": "Center"
}

Posição​

O objeto position diz em que página a assinatura fica e em que lugar dela. Ele tem a página, a unidade de medida e uma das duas formas de escolher o retângulo: manual ou auto.

CampoDescrição
pageNumberA página: 1 é a primeira página; números negativos contam a partir do fim (-1 é a última página); 0 acrescenta uma nova página ao final do PDF, mas somente se o PDF ainda não tiver assinatura visível (caso contrário, usa a última página). Se omitido, vale 0. Um número de página além do número de páginas faz a assinatura falhar
measurementUnitsCentimeters ou PdfPoints (1/72 de polegada). Se omitido, usa-se o valor de measurementUnits em pdfSignatureOptions e, sem ele, Centimeters. Vale para todas as medidas da posição e para o container do texto
manualUm retângulo fixo na página: veja Posicionamento manual
autoUma região da página onde as assinaturas são colocadas uma após a outra: veja Posicionamento automático
pageOptimizationObsoleto. Também existe em pdfSignatureOptions, e o da posição tem precedência. As medidas em centímetros são escalonadas para um tamanho de papel de referência que o Rest PKI Core estima a partir das proporções da página (Letter, Legal ou, caso contrário, A4), a menos que pageOptimization informe o tamanho do papel (paperSize, como A4 ou Letter, ou Custom com customPaperSize) e a orientação (pageOrientation). Assim, em páginas de tamanho fora do padrão, como A3, os tamanhos acompanham a página: para ter tamanhos absolutos, use PdfPoints

Se manual e auto forem enviados juntos, vale auto. Se nenhum dos dois for, a assinatura falha.

Retângulos​

Os retângulos, como o retângulo de manual, o container de auto e o container do texto, são definidos pelos parâmetros left, top, right, bottom, width e height, que são margens relativas ao que contém o retângulo (a página ou o retângulo da assinatura). Você não preenche todos: o que você define decide como o retângulo se comporta.

Parâmetros do retângulo

O retângulo, em vermelho, tem as suas margens relativas ao que o contém. Não defina left, right e width juntos: na horizontal, dois dos três (ou só width) bastam, e o resto ocupa o espaço restante. Na vertical funciona do mesmo jeito, com top, bottom e height no lugar de left, right e width. Os exemplos abaixo mostram as formas de definir as dimensões horizontais. Para saber mais sobre como os retângulos funcionam, veja Definindo um container, do PKI SDK.

Fluido​

Se você define apenas left e right, o retângulo mantém as duas margens e a largura se estica para preencher o espaço restante.

Retângulo fluido

Ancorado à esquerda​

Se você define apenas left e width, o retângulo mantém a margem esquerda e a largura. A margem direita ocupa o espaço restante.

Retângulo ancorado à esquerda

Ancorado à direita​

Se você define apenas right e width, o retângulo mantém a margem direita e a largura. A margem esquerda ocupa o espaço restante.

Retângulo ancorado à direita

Centralizado​

Se você define apenas width, o retângulo é centralizado horizontalmente com a largura dada.

Retângulo centralizado

Posicionamento manual​

Em manual, o retângulo da assinatura é fixo, relativo à página. Por exemplo, um retângulo de 7 por 3 cm, com margem de 2,5 cm das bordas esquerda e inferior:

"position": {
"pageNumber": 1,
"measurementUnits": "Centimeters",
"manual": { "left": 2.5, "bottom": 2.5, "width": 7, "height": 3 }
}

Posicionamento manual

Posicionamento automático​

Em auto, você define um container, uma região da página, e o tamanho de cada assinatura, e o Rest PKI Core coloca as assinaturas uma após a outra dentro do container. Serve para documentos com vários signatários, já que você não sabe a posição de cada um.

Posicionamento automático: o container e o retângulo da assinatura

CampoDescrição
containerA região da página que recebe as assinaturas, como um retângulo. Obrigatório
signatureRectangleSizeA largura (width) e a altura (height) do retângulo de cada assinatura. Obrigatório
rowSpacingO espaço entre as linhas. Padrão: 0
horizontalDirectionLeftToRight (padrão) ou RightToLeft: a direção em que uma linha é preenchida
verticalDirectionTopDown (padrão) ou BottomUp: a direção em que as linhas se empilham

Para escolher a posição de uma assinatura, o Rest PKI Core olha a última assinatura visível que já está na página, não importa quem a fez nem com qual ferramenta. Se a linha ainda tiver espaço para outro retângulo do mesmo tamanho, a nova assinatura vai para essa linha. Caso contrário, vai para uma nova linha, abaixo (TopDown) ou acima (BottomUp) da anterior, separada dela por rowSpacing. Cabem em uma linha tantas assinaturas quanto o número inteiro de vezes que a largura da assinatura cabe na largura do container. As linhas são justificadas: as colunas de uma linha se distribuem por igual pela largura do container, a primeira encostada em uma borda e a última na outra, então há espaços entre as assinaturas (cerca de 0,73 cm com o preset Footnote, em A4 em retrato).

Posicionamento automático: as assinaturas dentro do container

aviso

Quando o container está cheio, a assinatura é feita mesmo assim, mas sem representação visual, e nenhum erro é retornado. Dimensione o container para o número de signatários esperado. O Rest PKI Core não procura espaços livres no container nem confere o restante do conteúdo da página.

Presets​

Os presets devolvem um objeto position com a geometria usual, pronto para ser usado como está, no campo position da representação visual. São rotas GET que não precisam de autenticação:

RotaParâmetrosPosição
GET {endpoint}/Api/PadesVisualPositioningPresets/FootnotepageNumber (padrão -1, a última página); rows (padrão 1)Um rodapé: as assinaturas ficam no fim da página, em um container com margens de 1 cm à esquerda, à direita e embaixo e altura para o número de linhas dado, preenchido de cima para baixo, da esquerda para a direita
GET {endpoint}/Api/PadesVisualPositioningPresets/FootnoteBottomUppageNumber (padrão -1, a última página)O container é a página inteira, menos uma margem de 1 cm em cada lado, e as linhas se empilham de baixo para cima
GET {endpoint}/Api/PadesVisualPositioningPresets/NewPageNenhumAs assinaturas vão em uma nova página, com margem de 1 cm, como em pageNumber 0

Os três presets usam retângulos de assinatura de 4,2 x 1,8 cm, com espaço de 0,3 cm entre as linhas. Em uma página A4 em retrato, isso dá 4 assinaturas por linha.

Por exemplo, GET {endpoint}/Api/PadesVisualPositioningPresets/Footnote?pageNumber=-1&rows=2 devolve uma posição para duas linhas de assinaturas no fim da última página, o que comporta até 8 assinaturas em A4 em retrato.

Exemplos​

Rodapé com uma única linha​

As assinaturas ficam no fim da última página, em uma única linha: em A4 em retrato, até 4 assinaturas. É o preset Footnote com uma linha, com texto e imagem. Em uma sessão de assinatura:

POST {endpoint}/api/signature-sessions
{
...
"pdfSignatureOptions": {
"visualRepresentation": {
"text": {
"text": "Assinado digitalmente por {{name}}\nCPF: {{br_cpf_formatted}}",
"fontSize": 9,
"includeSigningTime": true,
"horizontalAlign": "Left",
"container": { "left": 0.2, "top": 0.2, "right": 0.2, "bottom": 0.2 }
},
"image": {
"resource": { "url": "https://example.com/seal.png" },
"opacity": 40,
"horizontalAlign": "Right",
"verticalAlign": "Center"
},
"position": {
"pageNumber": -1,
"measurementUnits": "Centimeters",
"auto": {
"container": { "left": 1.0, "right": 1.0, "bottom": 1.0, "height": 1.8 },
"signatureRectangleSize": { "width": 4.2, "height": 1.8 },
"rowSpacing": 0.3,
"horizontalDirection": "LeftToRight",
"verticalDirection": "TopDown"
}
}
}
}
}

Um quinto signatário não teria representação visual: veja o aviso acima.

Os PKI Suite Samples usam esse tipo de representação visual, com posicionamento automático na última página e um retângulo de assinatura maior:

Duas linhas, para até 8 signatários​

Para duas linhas, a altura do container é a altura de duas linhas mais o espaço entre elas: 2 x 1,8 + 0,3 = 3,9 cm. O restante é igual ao exemplo anterior, então só a position é mostrada:

"position": {
"pageNumber": -1,
"measurementUnits": "Centimeters",
"auto": {
"container": { "left": 1.0, "right": 1.0, "bottom": 1.0, "height": 3.9 },
"signatureRectangleSize": { "width": 4.2, "height": 1.8 },
"rowSpacing": 0.3,
"horizontalDirection": "LeftToRight",
"verticalDirection": "TopDown"
}
}

Um retângulo fixo, em uma assinatura em duas etapas​

Uma assinatura em uma posição fixa da primeira página, só com o texto:

POST {endpoint}/api/signature
{
"file": {
"content": "JVBERi0x...",
"name": "document.pdf"
},
"certificate": {
"content": "MIIG..."
},
"signatureType": "Pdf",
"pdfSignatureOptions": {
"visualRepresentation": {
"text": {
"text": "Assinado por {{name}}",
"includeSigningTime": true
},
"position": {
"pageNumber": 1,
"measurementUnits": "Centimeters",
"manual": { "left": 2.5, "bottom": 2.5, "width": 7, "height": 3 }
}
}
}
}

No .NET​

O cliente .NET não tem auxiliares dedicados para a representação visual: você a monta com os modelos da API, no namespace Lacuna.RestPki.Api.PadesSignature, e a define na propriedade VisualRepresentation de PdfSignatureOptions (ou de StampPdfOptions, em um carimbo). As classes são PadesVisualRepresentationModel, com PadesVisualTextModel, PadesVisualImageModel (cujo Resource é um ResourceContentOrReference) e PadesVisualPositioningModel, que por sua vez tem um PadesVisualAutoPositioningModel ou, no posicionamento manual, um PadesVisualRectangleModel. As propriedades têm os nomes dos campos JSON descritos acima, em PascalCase. Veja como o exemplo em .NET monta uma.

Veja também​

Ver em Markdown