Vamos a cifrar y descifrar archivos con PHP de dos maneras; la primera usando una clave “general” y otra con una contraseña.
Para cifrar y descifrar vamos a usar la librería php-encryption.
La diferencia es que con el segundo ejemplo podremos hacer que los usuarios tengan sus archivos cifrados con una contraseña que solo ellos sepan, y cada uno tendrá una clave distinta.
En un post anterior vimos cómo encriptar texto o datos como strings / variables en PHP.
Ahora vamos a ver cómo cifrar o encriptar archivos completos con PHP; es decir, no encriptar texto, sino archivos como imágenes, vídeos, documentos, etcétera.
Vamos a usar la misma librería que en el post citado. Si no la has instalado, ejecuta:
composer require defuse/php-encryption
En caso de que Composer no esté instalado mira cómo instalar Composer aquí; y si quieres adaptar tu proyecto puedes ver un tutorial aquí.
Nota: si quieres comprobar que estás descargando el archivo real y que nadie lo interceptó en el camino puedes descargar el archivo phar y comprobar las firmas.
Después de instalarla simplemente hay que requerir el autoload como veremos en los ejemplos.
require_once "vendor/autoload.php";
Recuerda que la clave puede ser generada con el ejecutable llamado generate-defuse-key ubicado en vendor/bin.
La clave debe estar guardada en un lugar seguro al que solo tú tengas acceso, pues quien tenga acceso podrá cifrar y descifrar a su gusto.
<?php
/**
* Cifrar un archivo con php-encryption
*
* https://parzibyte.me/blog
*
*/require_once "vendor/autoload.php";
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use Defuse\Crypto\Exception\IOException;
use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
use Defuse\Crypto\File;
use Defuse\Crypto\Key;
// Cualquier archivo es válido
// El archivo que se va a cifrar
$rutaArchivoEntrada = __DIR__ . "/kotlin.png";
// El archivo de salida; es decir, el que estará cifrado
$rutaArchivoSalida = __DIR__ . "/kotlin.cifrado.png";
// No olvides guardar la clave en un lugar seguro; aquí lo pongo así de simple para ejemplos de
// simplicidad
$contenido = file_get_contents("clave.txt");
// Cargar la clave desde una cadena ASCII (pues la clave no es tan legible ni entendible como una simple cadena)
$clave = Key::loadFromAsciiSafeString($contenido);
// Y ya podemos cifrar el archivo
try {
File::encryptFile($rutaArchivoEntrada, $rutaArchivoSalida, $clave);
echo "Archivo $rutaArchivoEntrada cifrado dentro de $rutaArchivoSalida";
// Opcionalmente podrías eliminar el original:
# unlink($rutaArchivoEntrada);
# El manejo de excepciones es opcional ;)
} catch (IOException $e) {
echo "Error leyendo o escribiendo archivo. Verifica que el archivo de entrada exista y que tengas permiso de escritura";
} catch (EnvironmentIsBrokenException $e) {
echo "El entorno está roto. Normalmente es porque la plataforma actual no puede encriptar el archivo de una manera segura";
} catch (WrongKeyOrModifiedCiphertextException $e) {
echo "La clave es errónea o alguien la intentó modificar, cuidado";
}
def00000180bb725822d130c3e64f1c8c4544f468b91cc42b640c5d7a06a0eb0d3aa9cec0b9f44e407fbc674611f82b71555a9bb4c7f5a17ff9bd328eeb797a3fd288797
En el ejemplo de código estoy cifrando una imagen usando una clave que obtengo leyendo un archivo de texto.
El método File::encryptFile($rutaArchivoEntrada, $rutaArchivoSalida, $clave)
toma la ruta de un archivo de entrada, lo cifra con la clave y el archivo cifrado lo pone en la ruta del archivo de salida.
Si quieres eliminar el archivo original simplemente usa unlink
.
Ahora veamos cómo se podría descifrar el archivo cifrado anteriormente, igual con una clave.
def00000180bb725822d130c3e64f1c8c4544f468b91cc42b640c5d7a06a0eb0d3aa9cec0b9f44e407fbc674611f82b71555a9bb4c7f5a17ff9bd328eeb797a3fd288797
<?php
/**
* Descifrar un archivo con php-encryption
*
* https://parzibyte.me/blog
*
*/require_once "vendor/autoload.php";
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use Defuse\Crypto\Exception\IOException;
use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
use Defuse\Crypto\File;
use Defuse\Crypto\Key;
// Cualquier archivo es válido
// El archivo que se va a descifrar
$rutaArchivoEntrada = __DIR__ . "/kotlin.cifrado.png";
// El archivo de salida; es decir, el que estará descifrado
$rutaArchivoSalida = __DIR__ . "/kotlin.png";
// No olvides guardar la clave en un lugar seguro; aquí lo pongo así de simple para ejemplos de
// simplicidad
$contenido = file_get_contents("clave.txt");
// Cargar la clave desde una cadena ASCII (pues la clave no es tan legible ni entendible como una simple cadena)
$clave = Key::loadFromAsciiSafeString($contenido);
// Y ya podemos descifrar el archivo
try {
File::decryptFile($rutaArchivoEntrada, $rutaArchivoSalida, $clave);
echo "Archivo $rutaArchivoEntrada descifrado dentro de $rutaArchivoSalida";
// Opcionalmente podrías eliminar el cifrado:
# unlink($rutaArchivoEntrada);
# El manejo de excepciones es opcional ;)
} catch (IOException $e) {
echo "Error leyendo o escribiendo archivo. Verifica que el archivo de entrada exista y que tengas permiso de escritura";
} catch (EnvironmentIsBrokenException $e) {
echo "El entorno está roto. Normalmente es porque la plataforma actual no puede encriptar el archivo de una manera segura";
} catch (WrongKeyOrModifiedCiphertextException $e) {
echo "La clave es errónea o alguien la intentó modificar, cuidado";
}
Es muy similar al proceso para cifrar un archivo con PHP, solo que ahora el archivo de entrada es el archivo previamente encriptado; y se invoca al método decryptFile
.
Lo digo de nuevo, para eliminar el archivo podrías usar unlink
.
Existe otra manera de cifrar todo el contenido de un archivo con PHP y la librería php-encryption, y es usar una contraseña.
No te confundas, la clave y la contraseña son cosas distintas.
Una contraseña puede ser proporcionada por un usuario (así, cada usuario del sistema podría tener sus archivos seguros sin depender de una clave general)
La clave es una clave que podría decirse es especial y tiene un formato predefinido además de ser segura, y se usa cuando el sistema es de un solo usuario.
Cifrar un archivo en PHP usando una contraseña es más fácil que encriptar un archivo usando la clave.
Ahora se invoca al método encryptFileWithPassword
cuyo uso se ve en el siguiente código:
<?php
/**
* Cifrar un archivo con php-encryption; usando una contraseña
* en lugar de la clave
*
* https://parzibyte.me/blog
*
*/require_once "vendor/autoload.php";
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use Defuse\Crypto\Exception\IOException;
use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
use Defuse\Crypto\File;
$password = "hunter2";
// Cualquier archivo es válido
// El archivo que se va a cifrar
$rutaArchivoEntrada = __DIR__ . "/script.js";
// El archivo de salida; es decir, el que estará cifrado
$rutaArchivoSalida = __DIR__ . "/script.cifrado.js";
try {
File::encryptFileWithPassword($rutaArchivoEntrada, $rutaArchivoSalida, $password);
echo "Archivo $rutaArchivoEntrada cifrado dentro de $rutaArchivoSalida";
// Opcionalmente podrías eliminar el original:
# unlink($rutaArchivoEntrada);
# El manejo de excepciones es opcional ;)
} catch (IOException $e) {
echo "Error leyendo o escribiendo archivo. Verifica que el archivo de entrada exista y que tengas permiso de escritura";
} catch (EnvironmentIsBrokenException $e) {
echo "El entorno está roto. Normalmente es porque la plataforma actual no puede encriptar el archivo de una manera segura";
} catch (WrongKeyOrModifiedCiphertextException $e) {
echo "La clave es errónea o alguien la intentó modificar, cuidado";
}
Pueden ocurrir excepciones, aunque el manejo de las mismas es opcional.
Como ves, encryptFileWithPassword
toma la ruta del archivo original, lo cifra usando la contraseña y finalmente el contenido lo escribe en la ruta del archivo de salida.
Para terminar el post veamos cómo descifrar o desencriptar un archivo con PHP usando una contraseña.
Recuerda que la misma contraseña que se utilizó para cifrar el contenido del archivo debe usarse para este proceso.
El código es el siguiente:
<?php
/**
* Descifrar un archivo con php-encryption; usando una contraseña
* en lugar de la clave
*
* https://parzibyte.me/blog
*
*/require_once "vendor/autoload.php";
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use Defuse\Crypto\Exception\IOException;
use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
use Defuse\Crypto\File;
$password = "hunter2";
// Cualquier archivo es válido
// El archivo que se va a descifrar
$rutaArchivoEntrada = __DIR__ . "/script.cifrado.js";
// El archivo de salida; es decir, el que estará descifrado
$rutaArchivoSalida = __DIR__ . "/script.js";
try {
File::decryptFileWithPassword($rutaArchivoEntrada, $rutaArchivoSalida, $password);
echo "Archivo $rutaArchivoEntrada descifrado dentro de $rutaArchivoSalida";
// Opcionalmente podrías eliminar el encriptado:
# unlink($rutaArchivoEntrada);
# El manejo de excepciones es opcional ;)
} catch (IOException $e) {
echo "Error leyendo o escribiendo archivo. Verifica que el archivo de entrada exista y que tengas permiso de escritura";
} catch (EnvironmentIsBrokenException $e) {
echo "El entorno está roto. Normalmente es porque la plataforma actual no puede encriptar el archivo de una manera segura";
} catch (WrongKeyOrModifiedCiphertextException $e) {
echo "La clave es errónea o alguien la intentó modificar, cuidado";
}
Ahora el método es decryptFileWithPassword
, el cual toma la ruta del archivo encriptado, la ruta en donde va a poner el archivo descifrado y la contraseña.
Como lo dije en los ejemplos, después de cifrar o descifrar los archivos con PHP puedes eliminarlos usando la función unlink
.
Por cierto, a los archivos les he puesto la extensión .cifrado para reconocerlos, pero el nombre puede ser cualquiera.
Los archivos que puedes cifrar con php-encryption son ilimitados, es decir, no hay una lista de extensiones o tipos.
Eso sí, recuerda que entre más grande sea el archivo, el proceso de cifrado y descifrado con PHP será más lento.
Nota: puedes ver el código en GitHub; los archivos de JavaScript e imágenes son para ilustrar el cifrado, no tienen nada que ver con este código.
El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…
En este post te voy a enseñar a designar una carpeta para imprimir todos los…
En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…
Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…
Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…
Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…
Esta web usa cookies.