MundoJSnode.jsAssinatura Digital de PDF no Node.js: Guia Prático

Assinatura Digital de PDF no Node.js: Guia Prático

Aprenda como assinar digitalmente PDFs com certificado A3 usando Node.js. Solução avançada e segura para NF-e em ambientes Windows e Linux. Otimize seu servidor para assinaturas digitais.

-

Ramos da Informática
JS TS IA

Pesquisa: Como você está usando IA na sua rotina Dev?

Responda em menos de 2 minutos e ajude a direcionar nossos próximos artigos técnicos, guias e conteúdos.

Responder Pesquisa →

Aprenda como assinar PDFs digitalmente usando Node.js e certificados A1 (.pfx). Guia prático com exemplos usando node-forge, pdf-lib e node-signpdf.

O certificado digital A1 é amplamente utilizado em aplicações fiscais, como emissão de Notas Fiscais Eletrônicas (NF-e), por ser armazenado no formato .pfx ou .pem, facilitando sua integração com sistemas hospedados, sejam eles em Windows ou Linux. Diferente do certificado A3, o A1 não requer dispositivos físicos, o que o torna ideal para servidores.

Neste guia avançado, vamos abordar como realizar a assinatura digital de PDFs com certificado A1 usando Node.js. O foco será em implementações que funcionem tanto em servidores Windows quanto Linux.

Dica de Leitura: Se você está trabalhando com Node.js para implementar a assinatura digital de PDFs com certificado A1, também pode estar interessado em melhorar a qualidade e segurança do seu código. Confira nosso artigo sobre como instalar e configurar SonarQube para projetos Node.js para garantir que seu projeto atenda aos padrões de qualidade e segurança necessários.


1. Entendendo o Certificado A1

O certificado A1:

  • Armazenamento: Arquivo digital no formato .pfx ou .pem.
  • Portabilidade: Pode ser carregado diretamente em servidores.
  • Uso em NF-e: Atende às exigências da SEFAZ para emissão de documentos fiscais.

2. Ferramentas e Bibliotecas Necessárias

Bibliotecas

  1. node-signpdf: Para inserir a assinatura no PDF.
  2. node-forge: Para manipular e carregar o certificado digital.
  3. pdf-lib: Para preparar o PDF com campos de assinatura.

Instalando Dependências

npm install node-signpdf pdf-lib forge

3. Configuração do Ambiente

Certifique-se de que o certificado A1 está disponível no servidor em formato .pfx ou .pem. Além disso, mantenha a chave privada protegida.

VAI GOSTAR: Pacotes e ferramentas Node.js que deveria conhecer

Ambientes

  • Windows: Certifique-se de que o arquivo .pfx está acessível e que o servidor tem permissões adequadas para lê-lo.
  • Linux: Verifique as permissões de leitura no diretório onde o certificado está armazenado.

4. Preparação do PDF

Antes de assinar, é necessário adicionar um campo de assinatura ao PDF.

Código para Adicionar Campo de Assinatura

const { PDFDocument } = require('pdf-lib');
const fs = require('fs');

async function preparePDF(inputPath, outputPath) {
  // Leia o PDF existente
  const pdfBytes = fs.readFileSync(inputPath);

  // Carregue o PDF usando pdf-lib
  const pdfDoc = await PDFDocument.load(pdfBytes);

  // Adicione uma anotação de campo para assinatura
  const pages = pdfDoc.getPages();
  const firstPage = pages[0];
  firstPage.drawText('Assinado digitalmente:', {
    x: 50,
    y: 50,
    size: 12,
  });

  // Salve o PDF modificado
  const modifiedPdfBytes = await pdfDoc.save();
  fs.writeFileSync(outputPath, modifiedPdfBytes);
}

preparePDF('documento.pdf', 'documento-preparado.pdf');

5. Assinatura Digital Usando o Certificado A1

5.1. Carregando o Certificado

Utilize o node-forge para carregar o certificado e a chave privada.

Código para Carregar o Certificado

const forge = require('node-forge');
const fs = require('fs');

function loadCertificate(pfxPath, passphrase) {
  const pfxBuffer = fs.readFileSync(pfxPath);
  const p12Asn1 = forge.asn1.fromDer(pfxBuffer.toString('binary'));
  const p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, false, passphrase);

  // Extraia a chave privada e o certificado
  let privateKey, certificate;
  p12.safeContents.forEach((safeContent) => {
    safeContent.safeBags.forEach((safeBag) => {
      if (safeBag.type === forge.pki.oids.keyBag) {
        privateKey = forge.pki.privateKeyToPem(safeBag.key);
      } else if (safeBag.type === forge.pki.oids.certBag) {
        certificate = forge.pki.certificateToPem(safeBag.cert);
      }
    });
  });

  return { privateKey, certificate };
}

// Exemplo de uso
const { privateKey, certificate } = loadCertificate('./certificado.pfx', 'SENHA_DO_CERTIFICADO');
console.log(privateKey, certificate);

5.2. Assinando o Hash do PDF

Código para Assinatura

const crypto = require('crypto');

function signData(dataToSign, privateKey) {
  const signer = crypto.createSign('RSA-SHA256');
  signer.update(dataToSign);
  return signer.sign(privateKey, 'base64');
}

// Exemplo de uso
const dataToSign = 'Hash do PDF'; // Substitua pelo hash real do PDF
const signature = signData(dataToSign, privateKey);
console.log('Assinatura:', signature);

6. Inserindo a Assinatura no PDF

Após gerar a assinatura, insira-a no PDF usando o node-signpdf.

Código para Inserir Assinatura

const { plainAddPlaceholder } = require('node-signpdf/dist/helpers');
const SignPdf = require('node-signpdf');
const fs = require('fs');

function signPDF(inputPath, outputPath, signature, certificate) {
  const pdfBuffer = fs.readFileSync(inputPath);

  // Adicione um placeholder para assinatura
  const pdfWithPlaceholder = plainAddPlaceholder({
    pdfBuffer,
    reason: 'Assinatura Digital Certificado A1',
  });

  // Assine o PDF
  const signer = new SignPdf();
  const signedPdf = signer.sign(pdfWithPlaceholder, {
    key: Buffer.from(privateKey),
    cert: Buffer.from(certificate),
    signature: Buffer.from(signature, 'base64'),
  });

  fs.writeFileSync(outputPath, signedPdf);
}

signPDF('documento-preparado.pdf', 'documento-assinado.pdf', signature, certificate);

7. Configuração para Servidores Windows e Linux

Windows

  • Certifique-se de que o arquivo .pfx está no diretório correto.
  • Use permissões adequadas para o usuário do serviço Node.js.

Linux

  • Configure as permissões do diretório para que o serviço Node.js possa acessar o arquivo.
  • Use caminhos absolutos ao carregar o certificado.

8. Validação e Testes

8.1. Validação do Certificado

Use ferramentas como o Adobe Acrobat ou validadores da SEFAZ para verificar a integridade do documento assinado.

8.2. Logs de Depuração

Adicione logs detalhados para depurar problemas:

console.log(‘Certificado carregado com sucesso.’);
console.log(‘Assinatura gerada:’, signature);
console.log(‘PDF assinado salvo em:’, outputPath);

9. Conclusão

Este guia apresenta um processo completo e avançado para assinar PDFs com o certificado digital A1 da SEFAZ em Node.js. O uso de um certificado A1 simplifica a implementação em servidores Windows e Linux, oferecendo flexibilidade e portabilidade.

Próximos Passos

  • Configure scripts para automação em um servidor Node.js.
  • Implemente autenticação para proteger o acesso ao certificado.
  • Realize testes extensivos com documentos fiscais reais.

Com estas etapas, você estará pronto para integrar assinaturas digitais com Node.js em ambientes de produção.

english-interview-debugger.sh
$ grep -r "senior_dev_communication" ./career
[CRITICAL_ERROR] Código sênior detectado, mas fluência falhou no runtime.
Motivo: Travou na hora de explicar a arquitetura (System Design) em inglês para o gringo.

O mercado internacional não quer um robô de gramática. Quer um dev que saiba defender uma tomada de decisão técnica sob pressão. Destrave sua conversão na Preply com aulas particulares focadas em TI.

$ ./fix-english.sh --target=remote-job
Achar Professor Particular ➔

Como testar e validar a assinatura do PDF

1. Preparação

  1. Arquivos Necessários:
    • O PDF a ser assinado (ex.: input.pdf).
    • O certificado digital no formato .pfx (ex.: certificado.pfx) e sua senha.
  2. Dependências Instaladas:
    • Certifique-se de que o Node.js e as bibliotecas necessárias (node-signpdf) estão instalados:bashCopiar códigonpm install node-signpdf
  3. Código Configurado:
    • Verifique se o código aponta corretamente para os arquivos (input.pdf, certificado.pfx) e a senha está correta.

2. Execução

  1. Execute o código:bashCopiar códigonode seu_arquivo.js
  2. Verifique a saída:
    • O PDF assinado será salvo no diretório atual com o nome signed.pdf (ou o nome especificado no código).

3. Validação

  1. No Adobe Reader:
    • Abra o PDF assinado (signed.pdf).
    • Confira o status da assinatura:
      • Deve indicar Assinatura válida.
      • Verifique se aparece “O documento não foi alterado desde que a assinatura foi aplicada.”
  2. No Validador da ICP-Brasil:
    • Acesse o Validador da ICP-Brasil.
    • Faça o upload do PDF assinado.
    • Verifique se a assinatura está conforme as normas ICP-Brasil.
  3. Outros Validadores (Opcional):
    • Utilize o Certisign Verificador para testar compatibilidade.

Se o PDF não for reconhecido como válido, revise os seguintes pontos:

  • Certificado: Certifique-se de que o .pfx contém a chave privada e a cadeia de certificação completa.
  • Carimbo de Tempo: Verifique se o PDF possui um carimbo de tempo (opcional, mas recomendado).
  • Formato de Assinatura: Confirme que segue o padrão PAdES.

VAI GOSTAR: Mundo do Web Scraping com Node.js e Puppeteer

Fontes de referências, estudos e pesquisas.

Para aprofundar seu conhecimento sobre assinatura digital de PDFs utilizando certificados digitais no Node.js, especialmente no contexto de Nota Fiscal de Serviço Eletrônica (NFSe), seguem algumas referências úteis:

Artigos e Tutoriais:

  1. Assinatura Digital via JavaScript: Este repositório no GitHub demonstra como implementar a assinatura digital de documentos utilizando JavaScript, o que pode ser adaptado para Node.js. GitHub
  2. Assine documentos com assinaturas digitais usando a API REST no Node.js: Este artigo detalha como utilizar a API REST do GroupDocs.Signature Cloud para assinar documentos PDF e DOCX em Node.js. GroupDocs Blog
  3. Como instalar um certificado SSL no Node.js: Embora focado em certificados SSL, este tutorial fornece insights sobre a configuração de certificados em ambientes Node.js, o que é relevante para o uso de certificados digitais. SSL Dragon

Bibliotecas e Repositórios no GitHub:

  1. ns-nfe-node: Biblioteca em Node.js para emissão de Nota Fiscal Eletrônica (NFe) utilizando a API da NS Tecnologia. GitHub
  2. client-nodejs: Cliente oficial da API NFe.io para Node.js, facilitando a integração com serviços de emissão de notas fiscais. GitHub
  3. NFe-NodeJS: Repositório que demonstra a emissão de Nota Fiscal Eletrônica para Node.js utilizando a REST API da WebmaniaBR®. GitHub
  4. autenticacao-ICP-Brasil: Instruções para autenticar um token/certificado A1/A3 no site, apresentando o e-CPF ou e-CNPJ, com exemplos em PHP e Node.js. GitHub

Documentação Oficial:

  • NFe.io – Documentação para Desenvolvedores: Documentação oficial da NFe.io, incluindo bibliotecas para Node.js e exemplos de uso. NFe.io
  • GroupDocs.Signature Cloud SDK para Node.js: Documentação oficial do SDK, útil para implementar assinaturas digitais em diversos formatos de documentos.

Considerações Importantes:

  • Certificado Digital A3: Este tipo de certificado requer atenção especial devido ao seu armazenamento em dispositivos físicos, como tokens USB ou smart cards. A integração com Node.js pode demandar o uso de bibliotecas específicas para comunicação com esses dispositivos, como PKCS#11.
  • Ambientes Windows e Linux: A configuração e uso de certificados digitais podem variar entre sistemas operacionais. Certifique-se de instalar os drivers e middlewares adequados fornecidos pelo fabricante do certificado para cada ambiente.

Estas referências fornecerão uma base sólida para implementar a assinatura digital de PDFs em Node.js, especialmente no contexto de NFSe, utilizando certificados digitais A3.

PODE GOSTAR: Entrevista de técnica sobre Node.js: Perguntas e respostas

LEIA TAMBÉM: Livros e cursos grátis para DevOps e DevSecOps

VAI GOSTAR

Perguntas Frequentes (FAQ): Assinatura Digital no Node.js

Qual a diferença entre usar um Certificado A1 e um A3 no servidor?

O Certificado A1 é um arquivo digital em formato de software (geralmente .pfx ou .p12). Ele pode ser hospedado e lido diretamente pelo Node.js em servidores em nuvem (AWS, DigitalOcean, Heroku) através do File System (fs). Já o certificado A3 fica armazenado em hardware (Tokens USB ou Cartões). Para usar um A3, você precisa de um servidor físico local com o dispositivo plugado, tornando a escalabilidade em nuvem praticamente impossível sem middlewares específicos.

É seguro deixar o arquivo .pfx e a senha dentro do projeto Node.js?

Não é uma boa prática deixar o arquivo de certificado exposto no repositório ou a senha escrita em hardcode (direto no arquivo .js). O ideal é armazenar o caminho do arquivo e a senha do certificado em variáveis de ambiente (arquivos .env) ou usar gerenciadores de segredos profissionais, como o AWS Secrets Manager ou HashiCorp Vault, para evitar que chaves da empresa vazem via GitHub.

A assinatura feita no Node.js tem validade legal?

Sim, desde que o certificado digital (A1) utilizado pertença à raiz da ICP-Brasil (Infraestrutura de Chaves Públicas Brasileira) e esteja dentro da validade. O processo criptográfico demonstrado gera uma assinatura válida e reconhecida juridicamente, desde que não ocorra a quebra da cadeia de confiança. O Adobe Reader e a SEFAZ vão identificar o Hash PAdES corretamente.

Por que minha assinatura aparece como “Desconhecida” no Adobe Reader?

Isso acontece porque o Adobe Reader verifica se ele “confia” na raiz que emitiu o certificado. Como muitos certificados do Brasil são atrelados à Autoridade Certificadora (AC) Raiz Brasileira, e esta não vem pré-instalada por padrão em alguns Adobe Readers estrangeiros, a assinatura é exibida como válida, mas “identidade não verificada”. Basta orientar o usuário a confiar manualmente na cadeia da ICP-Brasil no próprio Adobe.

Ramos da Informática
JS TS IA

Pesquisa: Como você está usando IA na sua rotina Dev?

Responda em menos de 2 minutos e ajude a direcionar nossos próximos artigos técnicos, guias e conteúdos.

Responder Pesquisa →
Ramos da Informática
Ramos da Informáticahttps://ramosdainformatica.com.br
Ramos da Informática é um hub de comunidade dedicado a linguagens de programação, banco de dados, DevOps, Internet das Coisas (IoT), tecnologias da Indústria 4.0, cibersegurança e startups. Com curadoria de conteúdos de qualidade, o projeto é mantido por Ramos de Souza Janones.

Mais recentes

NVIDIA Lança Cosmos 3: Nova Plataforma de IA Física para Robôs Humanoides e Fábricas Inteligentes

NVIDIA apresenta plataforma full-stack para robôs humanoides, robotáxis e fábricas inteligentes Cosmos 3, robôs humanoides e ferramentas para robotáxis são...

Repositórios e Skills Essenciais para Claude Code, Cursor e Codex

Se você já integrou o Claude Code, Cursor ou Codex no seu fluxo de trabalho, sabe que o jogo...

17 Ferramentas No-Code para Validar Seu Negócio

No mundo dos negócios, construir um Produto Mínimo Viável (MVP) não pode ser sinônimo de queimar o caixa da...

Extensões PostgreSQL: Substitua Redis, MongoDB e Kafka com SQL

Dominar as extensões PostgreSQL deixou de ser apenas uma opção para se tornar a principal estratégia de arquitetura em...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

State of AI 2026: A Maturidade da Inteligência Artificial

A inteligência artificial deixou definitivamente o território das experimentações e se consolidou como uma peça de infraestrutura fundamental no...

Construindo um Servidor MCP Personalizado com Node.js

Um guia prático para construir seu próprio servidor MCP para enriquecer as respostas de ferramentas de IA com contexto...

Mais Lidos

Como Usar o Skills in Chrome no Brasil: Tutorial Completo de IA

A inteligência artificial já faz parte do nosso fluxo...

Optimize seu Currículo com AI do Google

Fazer um currículo não é uma missão simples. Encontrar...

50 Dicas do Claude Code: Melhores Práticas para Usar Todo Dia

Você já usa o Claude Code há tempo suficiente...

3 Componentes Web Incríveis para Frontend

Acelere seu desenvolvimento frontend com componentes web nativos. Conheça...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

Recursos da Comunidade

Carreira Internacional

JOB NA GRINGA

Meta de Salário Remoto
U$ 5.000/mês

O mapa completo para programadores do Brasil conquistarem contratos internacionais e mudarem de vida financeira.

  • Vagas exclusivas semanais: Membros acessam vagas com 7 dias de antecedência.
  • Workshops e lives gravadas: Buscar vagas não é óbvio. Nós te mostraremos como.
  • 498 Portais de vagas: Que contratam Brasileiros direto na sua dashboard.
  • Mentorias com Recrutadores: Encontros semanais ao vivo com Erika Linares.
  • Inglês diário com foco em conversação: Treine para entrevistas num ambiente sem julgamentos.
  • Suporte pós-contratação: Contabilidade e recebimento legal com a menor taxa.
Garantir Minha Vaga

Inscrição segura via Hotmart

Você vai gostarrelacionados
Continue aprendendo

E-Zine Dev Ramos

Quer dominar arquitetura e IA?

Junte-se a +10.000 profissionais. Receba semanalmente estratégias de Node.js, React e IA que nunca publicamos no blog.

Assinar Gratuitamente Zero spam. Cancele quando quiser.