# CyberCore Signing Protocol (CCSP/1) > **Especificação Técnica do Protocolo de Comunicação Local e API REST (Versão 1)** O **CyberCore Signing Protocol (CCSP)** é o protocolo padrão para comunicação local entre aplicações web rodando no navegador do usuário e o agente desktop **CyberCore Signer**. A versão atual especificada neste documento é a **CCSP/1**. --- ## 1. Princípios de Segurança e Isolamento O protocolo CCSP/1 adota o princípio de menor privilégio e segurança em profundidade: 1. **Loopback Estrito (`127.0.0.1`):** O servidor HTTP local vincula seu socket exclusivamente ao endereço IP `127.0.0.1` na porta padrão `21325`. O agente rejeita escuta em `0.0.0.0`, prevenindo qualquer acesso proveniente da rede local (LAN) ou externa (WAN). 2. **Validação de Cabeçalhos e DNS Rebinding:** O agente valida o cabeçalho `Host` para garantir que as requisições se originem estritamente de `127.0.0.1:21325` ou `localhost:21325`. 3. **Controle de Origem (CORS):** Todas as respostas incluem cabeçalhos CORS restritivos. Métodos HTTP `OPTIONS` prévios (preflight) são tratados para liberar apenas métodos e headers homologados (`Content-Type`, `Origin`, `X-CyberCore-AppId`). 4. **Handshake de Autorização de Aplicações:** Nenhuma página web desconhecida pode listar certificados ou solicitar assinaturas. Uma aplicação deve se identificar (`POST /ccsp/v1/authorize`) e obter aprovação explícita do usuário via diálogo nativo do sistema operacional. 5. **Proteção Anti-Replay com Nonce e TTL:** Todas as chamadas de assinatura exigem um identificador pseudoaleatório `nonce` único e um timestamp de expiração (`expires_at`). Requisições com nonces repetidos são sumariamente rejeitadas com erro estruturado `REPLAY_DETECTED`. 6. **Privacidade Criptográfica por Digest:** Por padrão, a aplicação web calcula o hash SHA-256 no próprio navegador utilizando a Web Crypto API nativa e envia apenas o digest de 32 bytes (em Base64). O documento confidencial nunca trafega para o agente e a chave privada nunca sai do computador ou do chip criptográfico do usuário. 7. **Trava FIFO Serializada (`signLock`):** O processamento de assinaturas físicas em smartcards/tokens USB A3 é serializado em fila FIFO para evitar colisões no hardware mono-thread do middleware do fabricante. --- ## 2. Visão Geral dos Endpoints (CCSP/1) | Método | Endpoint | Finalidade | Autenticação Requerida | |---|---|---|---| | `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 | | `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 | --- ## 3. Especificação Detalhada dos Endpoints ### 3.1 `GET /ccsp/v1/status` Verifica se o agente desktop está instalado, em execução e pronto para operações criptográficas. #### Requisição ```http GET /ccsp/v1/status HTTP/1.1 Host: 127.0.0.1:21325 Origin: https://meusistema.empresa.com.br ``` #### Resposta de Sucesso (`200 OK`) ```json { "version": "1", "status": "ready", "agent": "CyberCore Signer", "agent_version": "0.1.0", "os": "Windows 11", "timestamp": "2026-10-11T20:45:00Z" } ``` --- ### 3.2 `POST /ccsp/v1/authorize` Inicia o handshake para autorizar uma nova aplicação web. Quando a aplicação ainda não foi homologada pelo usuário, o CyberCore Signer suspende a requisição e exibe um modal nativo na tela do desktop para confirmação. #### Cabeçalhos - `Content-Type: application/json` - `Origin: https://meusistema.empresa.com.br` #### Payload da Requisição ```json { "version": "1", "application_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Portal Jurídico e Tributário" } ``` #### Resposta de Sucesso (`200 OK`) ```json { "version": "1", "status": "authorized", "application_id": "550e8400-e29b-41d4-a716-446655440000", "message": "Aplicação autorizada pelo usuário com sucesso." } ``` #### Resposta de Recusa do Usuário (`403 Forbidden`) ```json { "version": "1", "status": "error", "error_code": "APPLICATION_NOT_AUTHORIZED", "message": "O usuário recusou a autorização para esta aplicação." } ``` --- ### 3.3 `GET /ccsp/v1/certificates` Retorna a lista de certificados digitais atualmente disponíveis e aptos para assinatura no sistema (A1 importados e A3 conectados via Windows Store ou PKCS#11). #### Cabeçalhos / Parâmetros - `Origin`: Origem web autorizada. - `X-CyberCore-AppId` (Header) ou `?application_id=uuid` (Query Param). #### Resposta de Sucesso (`200 OK`) ```json { "version": "1", "status": "success", "certificates": [ { "id": "win-4340656a", "alias": "MARIA DA SILVA:12345678900", "common_name": "MARIA DA SILVA:12345678900", "subject_dn": "CN=MARIA DA SILVA:12345678900, OU=Autenticado por AR, O=ICP-Brasil, C=BR", "issuer_dn": "CN=AC SERPRO v5, OU=Servico Federal de Processamento de Dados, O=ICP-Brasil, C=BR", "type": "A3", "provider_id": "provider-win-store", "device_name": "Token USB / Smart Card (Windows CAPI/CNG)", "valid_from": "2025-01-10T10:00:00Z", "valid_to": "2028-01-10T10:00:00Z", "serial_number": "72910482910482019482", "cpf": "12345678900", "cnpj": null, "can_sign": true, "status": "AVAILABLE" } ] } ``` --- ### 3.4 `POST /ccsp/v1/sign` Solicita a assinatura digital local do digest informado com o certificado escolhido. #### Payload da Requisição ```json { "version": "1", "request_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d", "application_id": "550e8400-e29b-41d4-a716-446655440000", "operation": "sign", "algorithm": "SHA256withRSA", "digest": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", "certificate_hint": "win-4340656a", "document_name": "contrato_prestacao_servicos.pdf", "document_type": "PDF", "document_size": 1474560, "origin": "https://meusistema.empresa.com.br", "nonce": "c4ca4238a0b923820dcc509a6f75849b", "expires_at": "2026-10-11T20:50:00Z" } ``` > **Garantia WYSIWYS (What You See Is What You Sign):** > O agente CyberCore Signer apresenta ao usuário, antes de qualquer operação criptográfica: > - **Aplicação Solicitante e Origem Web:** Exibe a URL de origem da página web chamadora para prevenir ataques de personificação (Spoofing). > - **Nome e Tamanho do Documento:** Se informados via `document_name` e `document_size` (em bytes), são apresentados de forma legível (ex: `1.4 MB`). > - **Hash do Documento (SHA-256 Digest):** Formatado em blocos legíveis de 4 caracteres (ex: `A1B2 C3D4 ...`) em tipografia monoespaçada para fácil conferência humana. > - **Certificado e Dispositivo:** Exibe titular, CPF/CNPJ, tipo A1/A3 e algoritmo de assinatura. #### Resposta de Sucesso (`200 OK`) ```json { "version": "1", "request_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d", "status": "signed", "signature": "MEUCIQDq95kZc...Base64...", "certificate": "MIIFazCCBF...Base64...", "certificate_chain": [ "MIIFazCCBF...Base64...", "MIIEazCCA1...Base64..." ], "algorithm": "SHA256withRSA", "subject_name": "MARIA DA SILVA", "subject_cpf_cnpj": "12345678900", "document_name": "contrato_prestacao_servicos.pdf", "document_type": "PDF" } ``` --- ### 3.5 `POST /ccsp/v1/authenticate` Executa o login criptográfico de um usuário em sistemas web através do mecanismo de desafio e resposta (*Challenge-Response*). #### Payload da Requisição ```json { "version": "1", "request_id": "8f3b201a-8c9d-4e5f-b012-3456789abcde", "application_id": "550e8400-e29b-41d4-a716-446655440000", "operation": "authenticate", "challenge": "session-nonce-random-server-token-998877", "certificate_hint": "win-4340656a", "purpose": "AUTHENTICATION", "nonce": "d3b07384d113edec49eaa6238ad5ff00", "expires_at": "2026-10-11T20:50:00Z" } ``` #### Resposta de Sucesso (`200 OK`) ```json { "version": "1", "request_id": "8f3b201a-8c9d-4e5f-b012-3456789abcde", "status": "authenticated", "signature": "MEQCIF61pP...Base64...", "certificate": "MIIFazCCBF...Base64...", "certificate_chain": [ "MIIFazCCBF...Base64...", "MIIEazCCA1...Base64..." ], "algorithm": "SHA256withRSA", "subject_name": "MARIA DA SILVA", "subject_cpf_cnpj": "12345678900" } ``` --- ### 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": "...", "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": "...", "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: ```json { "version": "1", "request_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d", "status": "error", "error_code": "PIN_INCORRECT", "message": "O PIN informado para o token A3 é inválido." } ``` ### Mapeamento de Status HTTP | Código HTTP | Erro Típico | Descrição | |---|---|---| | `400 Bad Request` | `USER_CANCELLED`, `PIN_INCORRECT`, `SIGNATURE_FAILED` | Requisição malformada, cancelamento pelo usuário ou falha de PIN | | `401 Unauthorized` | `APPLICATION_NOT_AUTHORIZED` | Aplicação não autorizada ou sem cabeçalho `X-CyberCore-AppId` | | `403 Forbidden` | `INVALID_ORIGIN` | Cabeçalho `Origin` não confere com o domínio cadastrado | | `404 Not Found` | `CERTIFICATE_NOT_FOUND`, `TOKEN_NOT_FOUND` | Certificado ou dispositivo físico ausente | | `409 Conflict` | `REPLAY_DETECTED` | Nonce já utilizado anteriormente na janela de validação | | `422 Unprocessable`| `REQUEST_EXPIRED`, `CERTIFICATE_EXPIRED` | Parâmetros sintaticamente válidos mas expirados temporalmente | | `500 Server Error` | `PKCS11_ERROR`, `PROVIDER_NOT_AVAILABLE` | Falha interna no middleware do fabricante ou driver criptográfico | | `503 Service Unavail`| `TOKEN_REMOVED`, `COMMUNICATION_ERROR` | Hardware desconectado ou serviço em recuperação | --- ## 5. Diagrama de Sequência Completo ```mermaid sequenceDiagram autonumber actor User as Usuário participant Browser as Aplicação Web (Browser) participant SDK as @cybercore/signer-sdk participant CCSP as CyberCore CcspServer (127.0.0.1) participant UI as CyberCore Desktop UI participant HW as Hardware Token / Windows MY Browser->>SDK: signer.sign({ digest, certId }) SDK->>CCSP: POST /ccsp/v1/sign (Headers, AppId, Nonce, Digest) CCSP->>CCSP: Valida Origin, AppId e Nonce (anti-replay) CCSP->>UI: Solicita confirmação visual (requestSignatureConfirmation) UI->>User: Exibe Diálogo Nativo (Aplicação, Documento, Certificado) User->>UI: Clica em "Assinar" opt Certificado A3 exige PIN UI->>User: Solicita PIN do Hardware User->>UI: Digita PIN end UI-->>CCSP: Confirmação concedida CCSP->>HW: signLock.lock() -> JCA/JCE Signature.sign() HW-->>CCSP: Bytes da assinatura + Cadeia X.509 CCSP->>CCSP: signLock.unlock() CCSP-->>SDK: 200 OK (signature Base64, cert, subject) SDK-->>Browser: Retorna resultado para a página web ```