Files
cybercore-signer/docs/CCSP.md

18 KiB

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

GET /ccsp/v1/status HTTP/1.1
Host: 127.0.0.1:21325
Origin: https://meusistema.empresa.com.br

Resposta de Sucesso (200 OK)

{
  "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

{
  "version": "1",
  "application_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Portal Jurídico e Tributário"
}

Resposta de Sucesso (200 OK)

{
  "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)

{
  "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)

{
  "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

{
  "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)

{
  "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

{
  "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)

{
  "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)

{
  "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

{
  "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)

{
  "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

{
  "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)

{
  "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:

{
  "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."
}

Lista Completa de Códigos de Erro Estruturados

Todos os códigos de erro são estáveis, estruturados e interoperáveis entre o backend Java e o SDK JavaScript:

Código de Erro (error_code) Descrição e Causa Raiz Mapeamento no SDK
CERTIFICATE_NOT_FOUND Certificado não encontrado pelo ID ou hint especificado CertificateNotFoundError
CERTIFICATE_EXPIRED Certificado ultrapassou a data limite de validade (notAfter) CertificateExpiredError
CERTIFICATE_INVALID Certificado corrompido, revogado ou com estrutura X.509 inválida CertificateInvalidError
PRIVATE_KEY_NOT_AVAILABLE Chave privada inacessível, protegida por hardware desconectado ou ausente PrivateKeyNotAvailableError
TOKEN_NOT_FOUND Nenhum token USB, smart card ou leitora física detectada TokenNotFoundError
TOKEN_REMOVED O dispositivo físico foi desconectado durante a operação TokenNotFoundError
PIN_REQUIRED O hardware criptográfico A3 exige digitação de PIN para desbloqueio PinRequiredError
PIN_INCORRECT O PIN digitado pelo usuário foi rejeitado pelo token (risco de bloqueio de PUK) PinIncorrectError
PKCS11_ERROR Falha interna no driver, middleware PKCS#11 ou DLL do fabricante CyberCoreError
SIGNATURE_FAILED Erro matemático na cifra assimétrica ou payload malformado SignatureFailedError
APPLICATION_NOT_AUTHORIZED A aplicação web solicitante não possui autorização concedida pelo usuário ApplicationNotAuthorizedError
REQUEST_EXPIRED O timestamp expires_at da requisição foi ultrapassado (timeout) RequestExpiredError
REPLAY_DETECTED O identificador nonce já foi processado anteriormente (ataque de replay) ReplayDetectedError
INVALID_ORIGIN O cabeçalho Origin não confere com os domínios homologados para o AppId InvalidOriginError
INVALID_HOST O cabeçalho Host foi adulterado (tentativa de DNS Rebinding) CyberCoreError
UNSUPPORTED_ALGORITHM Algoritmo criptográfico solicitado não é suportado pelo provider UnsupportedAlgorithmError
USER_CANCELLED O usuário clicou explicitamente em 'Cancelar' no diálogo nativo do sistema UserCancelledError
PROVIDER_NOT_AVAILABLE Provedor criptográfico nativo indisponível na plataforma atual ProviderNotAvailableError
COMMUNICATION_ERROR Falha na camada de transporte HTTP local do loopback CyberCoreError
AGENT_NOT_RUNNING O agente desktop não está rodando em 127.0.0.1:21325 (lado SDK) AgentNotRunningError

5. Especificação JSON Schema e Versionamento

O contrato canônico e exaustivo de todos os endpoints e payloads do protocolo CCSP/1 está formalizado no arquivo:

Política de Versionamento e Retrocompatibilidade

  1. Identificador de Versão Maior (version: "1"):
    • O campo version em todos os requests e responses identifica a versão maior do protocolo. O agente desktop garante compatibilidade retroativa com todas as revisões do CCSP/1.
  2. Evolução Aditiva (Não Quebrante):
    • Novos campos opcionais de requisição e novos metadados informativos de resposta podem ser adicionados dentro da versão CCSP/1 sem quebrar clientes existentes. Clientes e servidores devem ignorar propriedades adicionais desconhecidas (additionalProperties tolerantes).
  3. Mudança Quebrante (Nova Versão Maior):
    • Qualquer alteração na semântica de autenticação, remoção de campos obrigatórios ou mudança estrutural de URLs exigirá a introdução de uma nova versão de protocolo (ex: CCSP/2 com prefixo /ccsp/v2/). O agente manterá os endpoints /ccsp/v1/ operacionais em paralelo para garantir transição suave.

6. Diagrama de Sequência Completo

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