feat: add SDK support for PDF document signing and visual seal customization tools

This commit is contained in:
Claudecio Martins
2026-10-11 18:34:47 -03:00
parent d8d2e6ee46
commit b46d8b665f
12 changed files with 3497 additions and 121 deletions
+121 -1
View File
@@ -29,7 +29,10 @@ O protocolo CCSP/1 adota o princípio de menor privilégio e segurança em profu
| `GET` | `/ccsp/v1/status` | Verifica integridade e status de prontidão do agente local | Nenhuma |
| `POST` | `/ccsp/v1/authorize` | Handshake de autorização inicial de uma aplicação web | Consentimento visual do usuário |
| `GET` | `/ccsp/v1/certificates` | Lista certificados digitais ICP-Brasil válidos e operacionais | Aplicação Autorizada |
| `POST` | `/ccsp/v1/sign` | Executa assinatura digital do digest informado | Aplicação Autorizada + Diálogo Nativo |
| `GET` | `/ccsp/v1/seals` | Lista temas e estilos visuais de selos suportados pelo agente | Aplicação Autorizada |
| `POST` | `/ccsp/v1/sign` | Executa assinatura digital do digest informado (PAdES/CAdES/XMLDSig) | Aplicação Autorizada + Diálogo Nativo |
| `POST` | `/ccsp/v1/sign-pdf` | Assina documento PDF em Base64 com selo posicionado e devolve PDF assinado | Aplicação Autorizada + Diálogo Nativo |
| `POST` | `/ccsp/v1/sign-xml` | Assina documento XML (XAdES-BES / XMLDSig) e devolve XML assinado | Aplicação Autorizada + Diálogo Nativo |
| `POST` | `/ccsp/v1/authenticate` | Realiza login seguro via desafio criptográfico (*Challenge-Response*) | Aplicação Autorizada + Diálogo Nativo |
---
@@ -214,6 +217,123 @@ Executa o login criptográfico de um usuário em sistemas web através do mecani
---
### 3.6 `GET /ccsp/v1/seals`
Retorna a lista de temas e estilos de selos visuais embutidos e instalados no CyberCore Signer.
#### Cabeçalhos
- `Origin: https://meusistema.empresa.com.br`
- `X-CyberCore-AppId: 550e8400-e29b-41d4-a716-446655440000`
#### Resposta de Sucesso (`200 OK`)
```json
{
"version": "1",
"status": "success",
"default_seal_id": "icp-brasil",
"seals": [
{
"id": "icp-brasil",
"name": "ICP-Brasil Institucional",
"description": "Estilo oficial corporativo com escudo de segurança vetorial e dados completos do titular",
"primary_color": "#0d47a1",
"secondary_color": "#0284c7",
"border_color": "#93c5fd",
"background_color": "#ffffff",
"text_color": "#0f172a",
"icon_style": "shield",
"width": 320,
"height": 82,
"default_cpf_mode": "FULL",
"default_include_date_time": true
},
{
"id": "gov-br",
"name": "Governamental (Padrão Gov.br / ITI)",
"description": "Faixa verde e ouro com declaração expressa de validade pela MP nº 2.200-2/2001",
"primary_color": "#047857",
"secondary_color": "#eab308"
}
]
}
```
---
### 3.7 `POST /ccsp/v1/sign-pdf`
Recebe um documento PDF em Base64, a página e as coordenadas desejadas (`x`, `y`, `scale`), aplica o selo visual e a assinatura digital PAdES (ISO 32000-1 / RFC 5652) e retorna o PDF assinado completo em Base64.
#### Payload da Requisição
```json
{
"version": "1",
"request_id": "b1b74288-7264-44a5-9271-bf10d32c5f11",
"application_id": "550e8400-e29b-41d4-a716-446655440000",
"operation": "sign-pdf",
"certificate_hint": "cert-1",
"pdf": "JVBERi0xLjQKJ...Base64...",
"page": 1,
"x": 60.0,
"y": 60.0,
"scale": 1.0,
"visible_seal": true,
"seal_theme_id": "icp-brasil",
"reason": "Aprovado e assinado digitalmente",
"location": "Curitiba, PR",
"nonce": "c301d011-8012-4261-bcfa-e7912ab5a420"
}
```
> **Selo Customizado Inline (`seal_custom`):**
> Em vez de `seal_theme_id`, a requisição pode fornecer um objeto `seal_custom` com cores hexadecimais, título customizado, ícone vetorial (`shield`, `certificate`, `lock`) e política de privacidade LGPD (`FULL`, `MASKED`, `HIDDEN`).
#### Resposta de Sucesso (`200 OK`)
```json
{
"version": "1",
"request_id": "b1b74288-7264-44a5-9271-bf10d32c5f11",
"status": "signed",
"signed_pdf": "JVBERi0xLjQKJ...PDF_ASSINADO_BASE64...",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"certificate": "MIIFazCCBF...Base64...",
"algorithm": "SHA256withRSA"
}
```
---
### 3.8 `POST /ccsp/v1/sign-xml`
Executa a assinatura digital de documentos XML em conformidade com o padrão XMLDSig W3C ou XAdES-BES ICP-Brasil (Padrão NF-e / NFC-e / CT-e / NFS-e). O documento assinado completo é devolvido diretamente ao sistema web.
#### Payload da Requisição
```json
{
"version": "1",
"request_id": "e44d32e1-455b-4357-9351-41c10d3b6f22",
"application_id": "550e8400-e29b-41d4-a716-446655440000",
"operation": "sign-xml",
"certificate_hint": "cert-1",
"xml": "<nfeProc versao=\"4.00\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">...</nfeProc>",
"profile": "XADES_BES",
"target_element_tag": "infNFe",
"target_element_id": "NFe35261012345678000199550010000001001234567890",
"nonce": "d80b0322-8012-4261-bcfa-e7912ab5a420"
}
```
#### Resposta de Sucesso (`200 OK`)
```json
{
"version": "1",
"request_id": "e44d32e1-455b-4357-9351-41c10d3b6f22",
"status": "signed",
"signed_xml": "<nfeProc versao=\"4.00\" ...><Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">...</Signature></nfeProc>",
"certificate": "MIIFazCCBF...Base64...",
"algorithm": "SHA256withRSA"
}
```
---
## 4. Estrutura Padrão de Erro e Códigos HTTP
Quando qualquer operação falha, o servidor local CCSP/1 responde com um objeto JSON padronizado e o código de status HTTP correspondente:
+52
View File
@@ -90,3 +90,55 @@ A posição e a página da estampa são parametrizáveis via `PdfSignatureOption
- **Filtro:** `/Filter /Adobe.PPKLite` e `/SubFilter /adbe.pkcs7.detached`.
- **Algoritmo:** `SHA256withRSA` / PKCS#1 v1.5 com digest SHA-256.
- **Salva Incremental:** Preserva a integridade de assinaturas anteriores e do documento original sem quebrar certificações prévias.
---
## 5. Ferramentas Web do SDK (@cybercore/signer-sdk)
O SDK web fornece componentes visuais nativos em JavaScript vanilla para aplicações web:
### 5.1 `PdfStampPicker` (Posicionador Visual de Selo)
Permite que o usuário final suba um PDF no navegador, folheie páginas, selecione cantos predefinidos ou arraste a estampa visual interativamente. O componente mapeia as coordenadas do canvas para o sistema de coordenadas do PDFBox (ISO 32000, com origem no canto inferior esquerdo) e gera em tempo real o payload JSON para a requisição.
```javascript
import { PdfStampPicker } from '@cybercore/signer-sdk';
const picker = new PdfStampPicker({
container: '#picker-container',
pdfSource: pdfArrayBuffer, // ou URL / Base64
initialScale: 1.0,
onPositionChange: (pos) => {
console.log('Página:', pos.page, 'X:', pos.x, 'Y:', pos.y);
}
});
// Obtém parâmetros prontos para a requisição CCSP
const stampConfig = picker.getStampConfig();
```
### 5.2 `PdfSealDesigner` (Criador & Personalizador de Selos)
Componente interativo com live preview em SVG vetorial para personalização de selos:
- Paleta de cores primária, secundária, fundo e texto.
- Ícones vetoriais (`shield`, `certificate`, `lock`) e upload de logotipo em Base64.
- Regras LGPD para mascaramento ou ocultação de CPF/CNPJ.
- Exportação da configuração JSON para envio inline via `seal_custom` na requisição `signPdfDocument()`.
### 5.3 Assinatura Completa via Base64 (`signPdfDocument`)
Permite enviar o PDF completo em Base64 e receber de volta o PDF assinado completo em Base64 para envio direto ao backend:
```javascript
const result = await signer.signPdfDocument({
certificateId: cert.id,
pdf: pdfArrayBuffer, // ou base64
page: stampConfig.page,
x: stampConfig.x,
y: stampConfig.y,
scale: stampConfig.scale,
seal_theme_id: 'icp-brasil', // ou seal_custom: customSealConfig
reason: 'Documento homologado',
location: 'São Paulo, SP'
});
console.log('PDF Assinado Base64:', result.signed_pdf);
console.log('SHA-256 do Documento Final:', result.sha256);
```
+24
View File
@@ -116,3 +116,27 @@ O serviço `XmlSigningService.validateXmlSignature(byte[] xmlBytes)` e o `Signat
2. **Validação de integridade dos dados de negócio:** Confere o digest do conteúdo ou elemento assinado.
3. **Validação de integridade do XAdES:** Confere o digest das propriedades qualificadas (`SignedProperties`), rejeitando qualquer adulteração no horário de assinatura (`SigningTime`) ou no certificado declarado.
4. **Inspeção de signatário e datação:** Extração de nome, documento (CPF/CNPJ), autoridade certificadora emissora e datação auditável.
---
## 5. Integração Web e SDK (@cybercore/signer-sdk)
As aplicações web autorizadas podem assinar arquivos XML diretamente via protocolo CCSP/1 com o método `signXmlDocument()`:
```javascript
import { CyberCoreSigner } from '@cybercore/signer-sdk';
const signer = new CyberCoreSigner();
// Assinatura de documento XML ou evento fiscal
const result = await signer.signXmlDocument({
certificateId: cert.id,
xml: xmlString, // texto puro ou xml_base64
profile: 'XADES_BES', // ou 'XMLDSIG'
targetElementTag: 'infNFe', // opcional
targetElementId: 'NFe35261012345678000199550010000001001234567890' // opcional
});
console.log('XML Assinado Retornado:', result.signed_xml);
console.log('Algoritmo Utilizado:', result.algorithm);
```