feat: add SDK support for PDF document signing and visual seal customization tools
This commit is contained in:
+121
-1
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
```
|
||||
|
||||
@@ -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);
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user