Assinatura digital com php

2,896 views
Skip to first unread message

Recígio poffo

unread,
Jul 21, 2010, 9:53:42 AM7/21/10
to phpav...@googlegroups.com
Olá amigos,

Bom, estou trabalhando no meu tcc e preciso assinar e datar digitalmente documentos. Da teoria, pelo menos de forma superficial eu compreendo, preciso aplicar isso no php.
Pesquisando por aí, encontrei bastante material, mas ainda tenho dúvidas. Tenho experiencia com zend framework e ele implementa alguns filtros de criptografia. Em parte usa o que já existe no php. Com o framework é possivel usar o filtro de openssl, mas não parece ser bem o que eu preciso para assinar documentos.
Encontrei a biblioteca http://pear.php.net/package/Crypt_RSA - Crypt_RSA, ela parece conseguir assinar e conferir assinatura, o que parece ser perfeito.

Gostaria de saber se alguem por aqui já trabalhou com algo nessa área e talvez pode dar umas dicas.

Att
Recigio Poffo

Ruan Carlos

unread,
Jul 21, 2010, 10:08:08 AM7/21/10
to phpav...@googlegroups.com
Não entendo muito do assunto e posso estar falando merda, mas no caso, você deseja oq?

Criptografia de documentos (Publica - Privada), ou.
Tenho uma página de internet e quero saber se essa página é deste site?

Não entendi exatamente o que seriam esses documentos assinados ai. (um .doc da vida?)

-----------------------------------------------------------------
Ruan Carlos
@ruanltbg
www.ruancarlos.com.br
Bacharel em Sistemas de Informação - Desenvolvedor web


--
Você recebeu esta mensagem porque está inscrito no Google Groups "PHP Avançado".
Para postar nesse grupo, envie e-mail phpav...@googlegroups.com
Para cancelar a sua inscrição neste grupo, envie um e-mail para phpavancado...@googlegroups.com
Para mais opções, visitem este grupo em http://groups.google.com.br/group/phpavancado
Tudo sobre php: http://www.phpavancado.net/
Documentação PHP: www.php.net

Reinaldo Borges

unread,
Jul 22, 2010, 7:56:48 AM7/22/10
to phpav...@googlegroups.com
Bom dia,

O padrão utilizado para datar e assinar qualquer tipo de arquivo é o PKCS7.
Ao assinar, você pode "embutir" o arquivo original dentro da assinatura, ou pode criar um arquivo de assinatura
separado do arquivo (o que eu acho mais adequado e mais fácil de trabalhar).

Vejas a funções openssl_pkcs7_* do PHP.


Não pesquisei ainda como "datar" o documento. Veja detalhes sobre ACT (Autoridades de Carimbo de Tempo).
A ideia básica é a seguinte: ao assinar um arquivo, você solicita um "carimbo de tempo" a uma ACT e inclui esse
carimbo na assinatura do arquivo.

Entre em contato com uma ACT para mais detalhes: http://actbr.crsec.com.br/
Depois compartilhe o que descobrir


Coloquei abaixo um post meu pra essa lista há algum tempo.

------

Navegadores Mozilla/Firefox oferecem uma função Javascript para assinar
uma string, usando o certificado do cliente (testei com certificado instalado
no browser e certificado em token).

Há também funções para gerar CSR (solicitação de certificado a uma CA)
direto no browser.
Há alguns controles ActiveX para IE que fazem a mesma coisa. Como não
uso Windows, ainda não testei. Se alguém quiser se aventurar...

Informações sobre essa função:
https://developer.mozilla.org/en/JavaScript_crypto

Detalhe importante: essa função consegue assinar mesmo que a conexão
não seja HTTPS/SSL.

O retorno da função é a mensagem assinada, em modo "opaco" PKCS7.
Uma assinatura normal teria a string original seguida da assinatura em base64.
A assinatura "opaca" codifica a string junto com a assinatura, tudo em base64.

Agora estou com outro problema: ao receber a mensagem assinada (PKCS7),
não consigo verifica-la com o PHP. A função openssl_pkcs7_verify() sempre
retorna um erro.

Estou usando uma solução alternativa, chamando o openssl direto pela
linha de comando. Essa solução encontrei neste link:

http://fsl.cenditel.gob.ve/plugins/scmsvn/viewcvs.php/*checkout*/tronco/firmas/signText2.php?content-type=text%2Fplain&root=said

A função básica é:

    function verifySig($msgFile,$sigFile,$
certFile) {
        $ca_dir = "/var/www/ssl";
        $ca_certs = $ca_dir."/allCACerts.crt";
        exec("openssl pkcs7 -inform PEM -in $sigFile -print_certs -outform PEM -out $certFile", &$saida, &$res);
        if($res!=0) {
            echo "Erro ao extrair certificados\n";
            return $res;
        }
        exec("openssl smime -verify -inform PEM -in $sigFile -content $msgFile -CApath $ca_dir -CAfile $ca_certs", &$saida,&$res);
        return $res;
    }

$msgFile é nome do arquivo com a mensagem original (não codificada, e não assinada)
$sigFile é o arquivo que contem a mensagem assinada (gerada pelo javascript signString)
$certFile é o nome de um arquivo onde serão gravados os certificados usados para assinar a string

A função precisa ainda que você configure o caminho e o nome de arquivo onde estarão os
certificados das CA's válidas para assinar a string.

A função retorna true se a assinatura for válida.

Ainda não descobri o motivo da função do PHP acusar erro.


Um código simples para assinar uma string (teste no Firefox):

        <script type='text/javascript'>
            function assinar() {
                document.getElementById("form1").mensagemAssinada.value =
                    window.crypto.signText( document.getElementById("form1").mensagem.value ,"ask");
                document.getElementById("form1").submit();
            }
        </script>
        <form name=form1 id=form1 method=post action='<?= $_SERVER['PHP_SELF']?>'>
            <input type=hidden name=mensagemAssinada>
           
            Mensagem a ser transmitida:
            <br>
            <textarea name=mensagem rows=4 cols=65><?= $_POST['mensagem'] ?></textarea>
           
            <br><br>
            <input type=button value="Assinar" onclick="assinar()">
        </form>






[]'s

Reinaldo Borges


Proteja o endereço de seus amigos como estou protegendo o seu.
Ao enviar mensagens para mais de um endereço use SEMPRE o
"Cco" (cópia oculta) ou "Bcc" (Blind carbon copy).


Em 21 de julho de 2010 10:53, Recígio poffo <rec...@gmail.com> escreveu:

--
338.gif

Recigio

unread,
Aug 5, 2010, 7:07:07 AM8/5/10
to PHP Avançado
Vamos lá,

Eu quero usar isso em arquivos, será um serviço disponibilizado numa
página da internet via upload ou web-service, no caso do web-service a
pessoa envia apenas o hash do arquivo. A idéia é usar sim um sistema
de chaves públicas e privadas.
O que eu consegui até agora foi o seguinte:

Assinando:

-A pessoa envia o arquivo
-Crio o hash do arquivo
- Assino ele com a biblioteca Crypt_RSA (http://pear.php.net/package/
Crypt_RSA)
- Pego a hora atual com ntp (http://ntp.br/)
- Coloco a hora junto com a assinatura e criptografo tudo denovo com a
chave pública

Verificando

-Envio o arquivo e a assinatura
-Faça praticamente o processo inverso usando a chave pública e
verifico se o hash é o mesmo. Nessa etapa a validade da chave privada
se verifica por que só a chave pública pode abrir. Assim como a
integridade do arquivo, pois o hash tem que ser o mesmo.

Eu usei esse Crypt_RSA para abstrair a parte de assinatura e parece
que funciona bem. Baixei um Open_SSL para gerar as chaves para mim.
Mas acredito que nem é necessário.
Agora restam ainda algumas dúvidas. Quanto ao carimbo temporal, o que
existe de específico nele. É muito diferente da minha idéia de embutir
a hora atual?

Desde já agradeço a todos! Desculpem a demora, meu Gmail não tinha me
mostrado as mensagens!

Samuel Zardo

unread,
Jan 26, 2015, 3:53:24 PM1/26/15
to phpav...@googlegroups.com
Boa tarde!

Você obteve sucesso neste projeto?
Conseguiu assinar e verificar os documentos?
Em um módulo de minha especialização o professor solicitou que fosse criado um sistema com esta finalidade, e como a linguagem que domino é o PHP resolvi fazer nela, mas estou encontrando pouco material explicativo a respeito.
Se puderem me mostrar seu projeto para que eu possa dar uma destravada no meu, agradeceria.

Obrigado!
Reply all
Reply to author
Forward
0 new messages