Skip to content

Instantly share code, notes, and snippets.

@tuchinski
Last active February 2, 2024 20:40
Show Gist options
  • Save tuchinski/06457902a8c59cb9f9437d7a3a6e97b4 to your computer and use it in GitHub Desktop.
Save tuchinski/06457902a8c59cb9f9437d7a3a6e97b4 to your computer and use it in GitHub Desktop.
assina um pdf com cert digital a1
<?php
require_once('vendor/autoload.php');
use setasign\Fpdi\Tcpdf\Fpdi;
Class PDF extends FPDI{
private $nome;
private $cpf;
function __construct($nome,$cpf){
parent::__construct();
$this->nome = $nome;
$this->cpf = $cpf;
}
function Header(){
}
function Footer(){
// Positionnement à 1,5 cm du bas
$this->SetY(-10);
// Police Arial italique 8
$this->SetFont('Helvetica','',6);
// Numéro de page
$textoFooter = "DOCUMENTO ASSINADO DIGITALMENTE POR $this->nome CPF $this->cpf VERIFIQUE O DOCUMENTO EM https://verificador.iti.gov.br";
$this->Cell(0,10,$textoFooter,'T',0,'C');
}
}
// echo ;
$diretorio = getcwd() . '/';
$nomeCertPFX = $diretorio . 'a.pfx';
$documentoParaAssinar = $diretorio . 'contrato.pdf';
$nomeCertCRT = $diretorio . 'tcpdf.crt';
$password = '15151515';
// * Gera o .crt a partir do .pfx
if (!file_exists('tcpdf.crt')){
shell_exec("openssl pkcs12 -in $nomeCertPFX -out $nomeCertCRT -nodes -passin pass:$password");
}
$p = file_get_contents($nomeCertCRT);
//Endereço do arquivo do certificado
//Obs.: Tentei usar o certificado no formato PFX e não funcionou
//Para converter use o comando no Prompt do Windows ou Terminal do Linux:
//openssl pkcs12 -in certificado.pfx -out tcpdf.crt -nodes
// $cert = '/home/tuchinski/Documentos/apoema/pdf/tcpdf.crt';
$pkcs12 = file_get_contents($nomeCertPFX);
// aqui a gente pega o certificado .crt, mas esse cara a gente tem que gerar
$cert = openssl_x509_read( $p );
$cert_parsed = openssl_x509_parse( $cert ,true);
// print_r($cert_parsed);
$nome_cpf = explode(":",$cert_parsed['subject']['CN']);
$res = [];
$openSSL = openssl_pkcs12_read($pkcs12, $res, $password);
if(!$openSSL) {
throw new ClientException("Error: ".openssl_error_string());
}
// // this is the CER FILE
// file_put_contents('CERT.cer', $res['pkey'].$res['cert'].implode('', $res['extracerts']));
// // this is the PEM FILE
// $cert = $res['cert'].implode('', $res['extracerts']);
// file_put_contents('KEY.pem', $cert);
// aqui a gente pega o certificado .pfx
if (openssl_pkcs12_read($pkcs12, $cert_info, $password)) {
// echo "Certificate read\n";
} else {
echo "Error: Unable to read the cert store.\n";
exit;
}
//Informações da assinatura - Preencha com os seus dados
$info = array(
'Name' => '',
'Location' => '',
'Reason' => '',
'ContactInfo' => '',
);
$pdf = new PDF($nome_cpf[0],$nome_cpf[1]);
//Configura a assinatura. Para saber mais sobre os parâmetros
//consulte a documentação do TCPDF, exemplo 52.
//Não esqueça de mudar 'senha' para a senha do seu certificado
// var_dump($cert);
//Importa uma página
$numPages = $pdf->setSourceFile($documentoParaAssinar);
// print_r($pdf->numPages());
// print_r($numPages);
for ($i=0; $i < $numPages; $i++) {
# code...
$pdf->AddPage();
// $text = "Documento assinado digitalmente por <b>$nome_cpf[0]</b>, CPF $nome_cpf[1]";
// $pdf->writeHTML($text, true, 0, true, 0);
$tplId = $pdf->importPage($i+1);
// $pdf->setSignature('file://'.$cert, 'file://'.realpath($cert), '','', 2, $info);
$pdf->setSignature($cert_info['cert'], $cert_info['pkey'], '','', 2, $info);
$pdf->useTemplate($tplId, 0, 0); //Importa nas medidas originais
// print a line of text
$pdf->setSignatureAppearance(10,10,10,10,1);
}
//Manda o PDF pra download
$pdf->Output();
@tuchinski
Copy link
Author

{ "name": "tuchinski/php-cert", "authors": [ { "name": "tuchinski", "email": "tuchinski12@gmail.com" } ], "require": { "tecnickcom/tcpdf": "^6.3", "setasign/fpdi": "^2.3" } }

@tuchinski
Copy link
Author

composer.json ai em cima

@MoisesAlvesSousa
Copy link

Como posso assinar um pdf ja assinado pela mesma classe acima?
Pois quando vou assina com outro certificado ela substitui a assinatura anterior e ponhe a a nova.

@vitormattos
Copy link

@MoisesAlvesSousa Limitação do FPDF, com este pacote não tem como.

Uso este pacote para fazer isto:
https://github.com/JSignPdf/jsignpdf-php
Utilizo no:
https://github.com/libresign/libresign

@webmaster-gk2
Copy link

Boa tarde,

Eu utilizo um sistema que o arquivo não é salvo, ele chama o TCPDF e realiza a montagem do pdf em questão, nesse caso eu não consigo setar um arquivo específico para a variável $documentoParaAssinar.

Alguém consegue me ajudar para que quando esse código for solicitado, ele se "autoassinar" ao invés de assinar o arquivo da variável $documentoParaAssinar?

@bielfelix-123milhas
Copy link

Agora é necessario tambem um qrcode, voces tem noção de como fazer esse qrcode?

@vitormattos
Copy link

No LibreSign tem como adicionar qrcode no rodapé de um documento:

Exemplo:

Screenshot_20230728_141119

Repositório:

https://github.com/LibreSign/libresign/

Um problema do FPDI para assinatura digital é que só permite uma única assinatura no documento. Quando adicionamos uma segunda assinatura a um documento já assinado, a assinatura anterior é apagada. No LibreSign é possível múltiplas pessoas assinarem um documento utilizando seus próprios certificados digitais (e-CPF ou e-CNPJ) ou certificados gerados pelo próprio LibreSign.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment