Pergunta

Tentando escrever algumas funções que criptografarão ou descriptografarão um arquivo e estou usando a classe encontrada aqui para tentar fazer isso:

http://www.itnewb.com/v/php-encrypion-decrypion-using-the-crypt-library-libmcrypt

A função de criptografia abaixo parece funcionar, na medida em que parece criptografar o arquivo e colocá -lo no diretório pretendido. Estou tentando descriptografar o arquivo agora, e ele apenas morre com a mensagem "Falha ao concluir a descriptografia" (que é codificada lá ...) Não há nada nos logs de erro do PHP, então não sei por que está falhando , mas como McRypt é inteiramente novo para mim, estou mais do que inclinado a acreditar que estou fazendo algo errado aqui ...

Aqui estão as funções:

//ENCRYPT FILE
    function encryptFile() {
        global $cryptastic;
        $pass = PGPPASS;
        $salt = PGPSALT;
        $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key.");

        if ($handle = opendir(PATH.'/ftpd')) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    $newfile = PATH.'/encrypted/'.$file.'.txt';
                    $msg = file_get_contents(PATH.'/ftpd/'.$file);
                    $encrypted = $cryptastic->encrypt($msg, $key) or die("Failed to complete encryption.");
                    $nfile = fopen($newfile, 'w');
                    fwrite($nfile, $encrypted);
                    fclose($nfile);
                    unlink(PATH.'/ftpd/'.$file);

                }
            }
            closedir($handle);
        }       


//DECRYPT FILE
    function inFTP() {
        global $cryptastic;
        $pass = PGPPASS;
        $salt = PGPSALT;
        $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key.");

        if ($handle = opendir(PATH.'/encrypted')) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    $newfile = PATH.'/decrypted/'.$file;
                    $msg = PATH.'/encrypted/'.$file;
                    $decrypted = $cryptastic->decrypt($msg, $key) or die("Failed to complete decryption.");
                    $nfile = fopen($newfile, 'w');
                    fwrite($nfile, $decrypted);
                    fclose($nfile);
                    //unlink(PATH.'/encrypted/'.$file);

                }
            }
            closedir($handle);
        }       
        //$crypt->decrypt($file);
    }
Foi útil?

Solução

Experimente esta classe PHP5 para criptografia usando McRypt. Nesse caso, está usando a criptografia AES. Você deseja alterar a chave para cada site em que você a usa. Se você não usar, pelo menos, pode guiá -lo a escrever sua própria versão.

<?php

class Encryption
{
    const CIPHER = MCRYPT_RIJNDAEL_128; // Rijndael-128 is AES
    const MODE   = MCRYPT_MODE_CBC;

    /* Cryptographic key of length 16, 24 or 32. NOT a password! */
    private $key;
    public function __construct($key) {
        $this->key = $key;
    }

    public function encrypt($plaintext) {
        $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE);
        $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
        $ciphertext = mcrypt_encrypt(self::CIPHER, $this->key, $plaintext, self::MODE, $iv);
        return base64_encode($iv.$ciphertext);
    }

    public function decrypt($ciphertext) {
        $ciphertext = base64_decode($ciphertext);
        $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE);
        if (strlen($ciphertext) < $ivSize) {
            throw new Exception('Missing initialization vector');
        }

        $iv = substr($ciphertext, 0, $ivSize);
        $ciphertext = substr($ciphertext, $ivSize);
        $plaintext = mcrypt_decrypt(self::CIPHER, $this->key, $ciphertext, self::MODE, $iv);
        return rtrim($plaintext, "\0");
    }
}

Uso:

$key = /* CRYPTOGRAPHIC!!! key */;
$crypt = new Encryption($key);
$encrypted_string = $crypt->encrypt('this is a test');
$decrypted_string = $crypt->decrypt($encrypted_string); // this is a test

Notas:

  • Esta aula não é segura para uso com dados binários (que podem terminar em NUL Bytes)
  • Esta classe não fornece criptografia autenticada.

Outras dicas

Embora a resposta Johns seja boa, o uso da codificação Base64 apenas para corrigir o problema de segurança binária é exagerado e tornará seus arquivos criptografados 33% maiores que o original. Aqui está a minha implementação PHP do formato de arquivo da AES Crypt, que resolve todos os problemas acima emitidos de forma transparente.

https://github.com/philios33/php-aes-file-encryption

É seguro binário e inclui criptografia autenticada. Como ele usa o formato de arquivo de cripto de código aberto (.aes), é totalmente compatível com outros softwares .aes.

https://www.aescrypt.com/

A interface é bem simples, esteja você criptografando ou descriptografando. Você apenas fornece um arquivo de origem e senha.

Você não deve usar o MCRYPT para criptografar/descriptografar dados. Conforme mostrado em sua pergunta e na resposta aceita, os dados não são autenticados, o que significa que ele será vítima de ataques de texto cifrado escolhidos.

Além disso, foi feito muito esforço para garantir que os desenvolvedores montassem as primitivas criptográficas corretamente. Como tal, em vez de McRypt, você deve usar o libsodium para seus projetos PHP. Libsodium é um garfo de NaCl. O NACL/Libsodium é escrito para remover muitas das armadilhas criptográficas em que os desenvolvedores se encontram, como ataques de tempo com a verificação de tags MAC.

O MCRYPT está depreciado no Php 7.1 e Libsodim é a maneira preferida de lidar com criptografia no PHP.

Usar o Libsodium em seu projeto PHP é fácil e seguro. Scott Arciszewski escreveu um extenso ebook sobre o uso de libsodium com PHP em https://paragonie.com/book/pecl-libsodium. Vale a pena ler para quem faz criptografia PHP.

Cakephp tem um bom implementação de Rijndael. Não estou postando código diretamente aqui porque não tenho certeza das ramificações legais.

Aqui estão os documentos da API para o Security::rijndael() método.

Se codificar um arquivo, você vai querer base64_encode() Antes de chamar esse método com 'encrypt', e base64_decode() Depois de chamar esse método com 'decrypt'

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top