Pregunta

Intentando escribir un par de funciones que encriptarán o descifrarán un archivo y estoy usando la clase que se encuentra aquí para tratar de lograr esto:

http://www.itnewb.com/v/php-encryption-decryption-using-the-mcrrypt-library-libmcrypt

La función de cifrado a continuación parece funcionar, ya que parece encriptar el archivo y colocarlo en el directorio previsto. Estoy tratando de descifrar el archivo ahora, y simplemente muere con el mensaje "No se pudo completar el descifrado" (que está codificado allí ...) No hay nada en los registros de errores de PHP, así que no estoy seguro de por qué está fallando , pero como McRypt es completamente nuevo para mí, estoy más que inclinado a creer que estoy haciendo algo mal aquí ...

Aquí están las funciones:

//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);
    }
¿Fue útil?

Solución

Pruebe esta clase PHP5 para el cifrado usando MCRYPT. En este caso está usando el cifrado AES. Querrá cambiar la clave para cada sitio en el que lo use. Si no lo usa al menos, puede guiarlo para escribir su propia versión.

<?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 clase no es segura para su uso con datos binarios (que pueden terminar en bytes nul)
  • Esta clase no proporciona cifrado autenticado.

Otros consejos

Si bien la respuesta de Johns es buena, el uso de la codificación base64 solo para solucionar el problema de seguridad binaria es excesiva y hará que sus archivos cifrados sean un 33% más grandes que el original. Aquí está mi implementación de PHP del formato de archivo de cripta AES que resuelve todos los problemas anteriores de manera transparente.

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

Es seguro binario e incluye cifrado autenticado. Dado que utiliza el formato de archivo de cripta AES de código abierto (.AES), es totalmente compatible con otro software .aES.

https://www.aescrypt.com/

La interfaz es bastante simple, ya sea que esté encriptando o descifrando. Simplemente le da un archivo de origen y contraseña.

No debe usar MCRYPT para cifrar/descifrar datos. Como se muestra en su pregunta, y en la respuesta aceptada, los datos no se autentican, lo que significa que será víctima de los ataques de texto cifrado elegidos.

Además, se ha hecho un gran esfuerzo para asegurarse de que los desarrolladores junten las primitivas criptográficas correctamente. Como tal, en lugar de MCRYPT, debe usar Libsodium para sus proyectos de PHP. Libsodium es una bifurcación de NaCl. NaCl/Libsodium está escrito para eliminar muchas de las trampas criptográficas en las que se encuentran los desarrolladores, como los ataques de tiempo con verificación de etiquetas MAC.

MCRYPT está en desuso en Php 7.1, y Libsodim es la forma preferida de manejar la criptografía en PHP.

El uso de Libsodium en su proyecto PHP es fácil y seguro. Scott Arciszewski ha escrito un extenso libro electrónico sobre el uso de Libsodium con PHP en https://paragonie.com/book/pecl-libsodium. Vale la pena leer para cualquiera que haga criptografía PHP.

Pastelera tiene un buen implementación de Rijndael. No publico código directamente aquí porque no estoy seguro de las ramificaciones legales.

Aquí están los documentos de la API Para el Security::rijndael() método.

Si codifica un archivo, querrá base64_encode() antes de llamar a este método con 'encrypt', y base64_decode() Después de llamar a este método con 'decrypt'

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top