Como Integrar Assinatura Digital em C# / .NET
Se você desenvolve em C# / .NET e precisa coletar assinaturas eletrônicas ou digitais com validade jurídica, este guia mostra o caminho completo: instalar o SDK oficial via NuGet, autenticar com OAuth2, criar uma sessão de assinatura, adicionar signatários, enviar o documento, validar webhooks com HMAC no ASP.NET Core e baixar o PDF assinado — tudo com código idiomático, async/await e HttpClient.
A API do SignDocs Brasil é REST e, portanto, agnóstica de linguagem. Mas usar o SDK .NET acelera bastante o trabalho: ele cuida da renovação do token, da serialização JSON com System.Text.Json e da tipagem dos modelos de requisição e resposta. Ainda assim, mostraremos também como cada passo é feito diretamente com HttpClient, para que você entenda o que acontece "por baixo" e possa integrar mesmo em runtimes mais antigos.
Ao final deste artigo você terá uma integração ponta a ponta funcionando em homologação. Se ainda estiver avaliando a plataforma como um todo, vale começar pela visão geral da API de assinatura digital e pelo quickstart de 5 minutos.
Pré-requisitos para integrar em .NET
Antes de escrever a primeira linha, garanta que seu ambiente atende ao mínimo necessário. A integração é leve e não exige nenhuma dependência nativa específica do Brasil — apenas um runtime .NET moderno e suas credenciais de API.
- .NET 6, 7 ou 8 (recomendado LTS). O SDK também funciona em .NET Framework 4.7.2+ via REST direto.
- Uma conta SignDocs com acesso à API. Veja como obter sua API key para gerar
client_ideclient_secret. - Acesso ao ambiente de homologação (
api-hml.signdocs.com.br) para testar sem custos. Detalhes em ambiente de homologação / sandbox. - Um endpoint HTTPS público (ou um túnel como
ngrok) caso queira receber webhooks durante o desenvolvimento.
POST /v1/signing-sessions devolve um checkout hospedado ou, via SDK front-end @signdocs-brasil/js, um checkout embutido em popup. Neste guia usamos predominantemente as signing sessions por serem o atalho mais rápido para colocar algo em produção.
Passo 1 — Instalar o SDK via NuGet
O pacote .NET oficial é distribuído pelo NuGet. Adicione-o ao seu projeto pela CLI do .NET ou pelo Package Manager Console do Visual Studio:
Caso prefira não usar o SDK, você precisa apenas das bibliotecas que já vêm na BCL: System.Net.Http para as requisições e System.Text.Json para a serialização. Nenhum pacote de terceiros é obrigatório para falar com a API REST.
Estrutura recomendada do projeto
Para uma aplicação ASP.NET Core, registre o cliente como serviço via injeção de dependência e mantenha as credenciais fora do código, em appsettings.json ou variáveis de ambiente:
Passo 2 — Autenticar com OAuth2 (client-credentials)
A autenticação segue o fluxo OAuth2 client-credentials: você troca client_id e client_secret por um bearer token JWT (assinado com ECDSA ES256), que acompanha cada requisição no header Authorization. O token expira em 15 minutos (expires_in: 900) e deve ser renovado quando vence. Para o detalhamento completo do fluxo, consulte o guia de autenticação OAuth2 da API.
O SDK encapsula isso, mas é instrutivo ver a obtenção do token diretamente com HttpClient:
Injetando o token automaticamente com um DelegatingHandler
O padrão idiomático em .NET é registrar um HttpClient nomeado via IHttpClientFactory e anexar um DelegatingHandler que adiciona o header Authorization a cada chamada, renovando o token de forma transparente:
Passo 3 — Criar uma sessão de assinatura
Com a autenticação resolvida, criar uma sessão é uma única chamada a POST /v1/signing-sessions. Você descreve o documento, os signatários e a política de assinatura (o profile). Para coletar uma assinatura com certificado ICP-Brasil, use o profile DIGITAL_CERTIFICATE — na API, o certificado é o A1 (em arquivo; para titulares de token A3, o aplicativo SignDocs oferece o assinador desktop). Para assinatura eletrônica, use perfis como CLICK_ONLY e CLICK_PLUS_OTP.
Veja a criação de uma sessão usando o SDK oficial:
Url sozinho não é o link compartilhável. Ele precisa ser combinado com o ClientSecret retornado, no formato {url}?cs={clientSecret}. Além disso, o convite por e-mail só é disparado automaticamente quando o Owner.Email for diferente do e-mail do signatário — caso contrário, entregue você mesmo o link. Veja o fluxo completo no quickstart de 5 minutos.
A mesma chamada com HttpClient puro
Se você não usar o SDK, monte o corpo da requisição com System.Text.Json e poste no client nomeado que já injeta o bearer token:
DIGITAL_CERTIFICATE como policy.profile. Um erro comum é enviar DIGITAL_SIGN_A1 nesse campo — isso retorna HTTP 400. DIGITAL_SIGN_A1 é apenas o tipo de uma etapa (step.type) na resposta, nunca um valor de profile. Para a lista completa de perfis, veja a seção de métodos de autenticação em o que é uma API de assinatura digital.
Passo 4 — Múltiplos signatários e ordem de assinatura
Quando o documento precisa de mais de uma assinatura, use a API de envelopes: um envelope agrupa até 100 signatários sobre o mesmo documento, e o SignerIndex de cada sessão define a posição na fila quando o modo é sequencial (por exemplo, o cliente antes do gestor):
Para um aprofundamento na sequência de coleta e nos modos sequencial vs. paralelo, consulte ordem de assinatura com múltiplos signatários; o ciclo de vida completo está em fluxos transacionais da API.
Passo 5 — Receber e validar webhooks no ASP.NET Core
Em vez de ficar consultando o status repetidamente (polling), o correto é registrar um webhook e deixar a API notificar sua aplicação a cada evento (SIGNING_SESSION.COMPLETED, TRANSACTION.COMPLETED, etc.). Cada entrega traz uma assinatura HMAC-SHA256 que você precisa validar para garantir a autenticidade. O detalhamento dos eventos e da estratégia de retry está em webhooks e eventos da API.
A regra de ouro no ASP.NET Core é validar a assinatura sobre o corpo bruto (raw body), antes de qualquer desserialização. Veja uma implementação com Minimal API:
CryptographicOperations.FixedTimeEquals para comparar a assinatura. Comparações comuns com == sobre strings são vulneráveis a timing attacks, em que um atacante infere a assinatura correta medindo diferenças de tempo de resposta. Responda HTTP 200 em poucos segundos e deixe qualquer trabalho pesado para uma fila — webhooks operam com semântica at-least-once, então seu handler deve ser idempotente, deduplicando pelo Id do evento. Se preferir não implementar a validação na mão, o SDK expõe o helper WebhookVerifier, que aplica exatamente essa checagem (HMAC sobre {timestamp}.{corpo}, tolerância de replay e comparação em tempo constante).
Passo 6 — Baixar o PDF assinado
Quando você recebe o evento TRANSACTION.COMPLETED, o documento final assinado — no padrão PAdES (nível baseline: assinatura + certificado + carimbo de hora do servidor + trilha de auditoria), com validade jurídica — fica disponível para download. O SDK devolve URLs temporárias de download; baixe o arquivo por streaming, sem carregar tudo na memória:
Além do PDF, a plataforma gera um pacote de evidências (.p7m) com a trilha de auditoria completa — IPs, geolocalização, métodos de autenticação e carimbos de tempo. Esse pacote é a prova jurídica da assinatura; saiba mais em evidence pack e prova jurídica. Qualquer pessoa pode conferir a autenticidade do documento no verificador público.
SDK oficial vs. REST puro: qual escolher?
Ambos os caminhos são válidos e atingem o mesmo resultado. A tabela abaixo ajuda a decidir conforme o contexto do seu projeto .NET:
| Critério | SDK oficial (NuGet) | REST puro (HttpClient) |
|---|---|---|
| Tipagem dos modelos | Classes/records prontos para request e response | Você define os DTOs ou usa JsonElement |
| Renovação do token OAuth2 | Automática, transparente | Você implementa (ex.: DelegatingHandler) |
| Dependências externas | Um pacote NuGet | Apenas a BCL (System.Net.Http, System.Text.Json) |
| Compatibilidade legada | Otimizado para .NET moderno | Funciona em .NET Framework 4.7.2+ |
| Velocidade de implementação | Mais rápida para o caminho feliz | Mais controle, porém mais código |
| Recomendado para | Maioria dos projetos novos | Casos com requisitos específicos de HTTP ou runtimes antigos |
IHttpClientFactory em vez de instanciar new HttpClient() manualmente — isso evita o esgotamento de sockets sob carga e habilita resiliência (retry, circuit breaker) via Polly. Para padrões REST além do básico — paginação, idempotência e tratamento de erros — vale conferir o guia de integração via REST puro com cURL, que vale para qualquer linguagem.
Boas práticas para a integração .NET em produção
- Nunca versione o client_secret. Use User Secrets em desenvolvimento e variáveis de ambiente, AWS Secrets Manager ou Azure Key Vault em produção.
- Tudo assíncrono. Use
async/awaitponta a ponta, propagueCancellationTokene evite.Resultou.Wait(), que causam deadlocks. - Idempotência nos webhooks. Deduplique pelo
iddo evento (em cache ou banco) para tratar entregas repetidas com segurança. - Responda rápido aos webhooks. Valide, enfileire e retorne 200. Processe o evento em um
BackgroundServiceou fila externa. - Comece em homologação. Aponte a
BaseUrlparaapi-hml.signdocs.com.bre lembre que as entidades de teste expiram em 7 dias. - Trate erros HTTP explicitamente. Use
EnsureSuccessStatusCodecom tratamento deHttpRequestExceptione logue o corpo de erro retornado pela API.
Se a sua integração for em outras stacks além do .NET, temos guias equivalentes — por exemplo, integrar assinatura digital em Java segue a mesma estrutura de OAuth2, sessões e webhooks, adaptada ao ecossistema JVM.
Perguntas Frequentes
Existe um SDK oficial de assinatura digital para C# / .NET?
Sim. O SignDocs Brasil mantém SDKs oficiais para TypeScript/Node, Python, Go, Java, PHP e C# / .NET. O pacote .NET é distribuído via NuGet e é compatível com .NET 6, 7 e 8, além de funcionar em projetos ASP.NET Core, worker services e aplicações console. O SDK encapsula a autenticação OAuth2, a serialização JSON e a renovação automática do token de acesso, mas você sempre pode recorrer à API REST diretamente com HttpClient caso prefira.
Qual versão do .NET preciso para usar a API de assinatura digital?
Recomendamos .NET 6 ou superior (LTS), pois oferece suporte nativo a async/await, HttpClient com IHttpClientFactory, System.Text.Json e minimal APIs no ASP.NET Core. A integração também funciona em .NET Framework 4.7.2+ usando chamadas REST diretas, mas o SDK oficial é otimizado para .NET moderno. Como a API é REST e baseada em HTTPS, qualquer runtime capaz de fazer requisições TLS 1.2+ consegue integrar.
Como autenticar minha aplicação .NET na API de assinatura?
A autenticação usa o fluxo OAuth2 client-credentials. Sua aplicação envia o client_id e client_secret ao endpoint de token e recebe um bearer token JWT, assinado com ECDSA (ES256) e com validade de 15 minutos, que deve ser incluído no header Authorization de cada requisição. Em .NET, o ideal é registrar um HttpClient nomeado via IHttpClientFactory com um DelegatingHandler que injeta e renova o token automaticamente, mantendo o client_secret em IConfiguration / secrets de ambiente, nunca no código-fonte.
Como validar a assinatura HMAC de um webhook no ASP.NET Core?
Leia o corpo bruto (raw body) da requisição antes de qualquer desserialização, calcule o HMAC-SHA256 do payload usando o webhook secret com a classe HMACSHA256 do namespace System.Security.Cryptography e compare com o header de assinatura recebido usando CryptographicOperations.FixedTimeEquals para evitar timing attacks. Valide também o timestamp para mitigar replay attacks. Só então desserialize o evento e responda com HTTP 200 rapidamente, deixando o processamento pesado para uma fila assíncrona.
Posso testar a integração .NET em um ambiente de homologação?
Sim. O SignDocs oferece um ambiente de homologação (sandbox) com host base api-hml.signdocs.com.br, onde você usa credenciais de teste e simula todo o ciclo de assinatura sem custos nem efeitos legais. Basta apontar a BaseUrl do SDK ou do HttpClient para o host de homologação. Vale lembrar que as entidades criadas em homologação têm TTL de 7 dias e são removidas automaticamente, então não dependa delas para testes de longa duração.
A API .NET suporta assinatura com certificado ICP-Brasil (A1 e A3)?
Sim. Ao criar a sessão ou transação você define o profile da política de assinatura como DIGITAL_CERTIFICATE para exigir certificado ICP-Brasil A1 — o formato usado em integrações via API, com um protocolo em duas fases em que a chave privada nunca sai do titular (para tokens A3, o aplicativo SignDocs oferece o assinador desktop). A assinatura digital acontece no fluxo conduzido pelo signatário; sua aplicação .NET orquestra a criação da sessão, o envio e o acompanhamento dos eventos, recebendo ao final um PDF no padrão PAdES com validade jurídica conforme a MP 2.200-2/2001.
Integre assinatura digital em C# / .NET hoje mesmo
SDK oficial via NuGet, OAuth2, Assinatura Expressa de uma chamada, webhooks com HMAC-SHA256 e certificado ICP-Brasil — tudo com validade jurídica e conformidade LGPD. O acesso à API é um plano sob medida, com sandbox de homologação gratuito para colocar sua aplicação .NET assinando antes de qualquer contrato.
Fale com o time comercial Conheça a plataforma grátis