Actualmente soy estudiante y estoy estudiando PHP, estoy tratando de hacer un cifrado / descifrado simple de datos en PHP. Hice algunas búsquedas en línea y algunas de ellas fueron bastante confusas (al menos para mí).
Esto es lo que estoy tratando de hacer:
Tengo una tabla que consta de estos campos (UserID, Fname, Lname, Email, Password)
Lo que quiero tener es cifrar todos los campos y luego descifrarlos (¿Es posible usarlos sha256
para cifrado / descifrado, si no algún algoritmo de cifrado?)
Otra cosa que quiero aprender es cómo crear una forma hash(sha256)
combinada con una buena "sal". (Básicamente, solo quiero tener una implementación simple de cifrado / descifrado, hash(sha256)+salt)
señor / señora, sus respuestas serían de gran ayuda y serían muy apreciadas. Gracias ++
fuente
Respuestas:
Prefacio
Comenzando con la definición de su tabla:
Aquí están los cambios:
Fname
,Lname
yEmail
se cifrarán mediante un cifrado simétrico, proporcionado por OpenSSL ,IV
campo almacenará el vector de inicialización utilizado para el cifrado. Los requisitos de almacenamiento dependen del cifrado y el modo utilizado; más sobre esto más adelante.Password
campo se codificará con un hash de contraseña unidireccional ,Cifrado
Cifrado y modo
La elección del mejor modo y cifrado de cifrado está más allá del alcance de esta respuesta, pero la elección final afecta el tamaño tanto de la clave de cifrado como del vector de inicialización; para esta publicación usaremos AES-256-CBC que tiene un tamaño de bloque fijo de 16 bytes y un tamaño de clave de 16, 24 o 32 bytes.
Clave de encriptación
Una buena clave de cifrado es un blob binario que se genera a partir de un generador de números aleatorios confiable. Se recomendaría el siguiente ejemplo (> = 5.3):
Esto se puede hacer una o varias veces (si desea crear una cadena de claves de cifrado). Manténgalos lo más privados posible.
IV
El vector de inicialización agrega aleatoriedad al cifrado y es necesario para el modo CBC. Lo ideal es que estos valores se utilicen solo una vez (técnicamente una vez por clave de cifrado), por lo que una actualización de cualquier parte de una fila debería regenerarla.
Se proporciona una función para ayudarlo a generar el IV:
Ejemplo
Encriptemos el campo de nombre, usando el anterior
$encryption_key
y$iv
; para hacer esto, tenemos que rellenar nuestros datos al tamaño del bloque:Requisitos de almacenamiento
La salida cifrada, como la IV, es binaria; El almacenamiento de estos valores en una base de datos se puede lograr utilizando tipos de columna designados como
BINARY
oVARBINARY
.El valor de salida, como el IV, es binario; para almacenar esos valores en MySQL, considere usar columnas
BINARY
oVARBINARY
. Si esta no es una opción, también puede convertir los datos binarios en una representación textual usandobase64_encode()
obin2hex()
, hacerlo requiere entre un 33% y un 100% más de espacio de almacenamiento.Descifrado
El descifrado de los valores almacenados es similar:
Cifrado autenticado
Puede mejorar aún más la integridad del texto cifrado generado agregando una firma generada a partir de una clave secreta (diferente de la clave de cifrado) y el texto cifrado. Antes de descifrar el texto cifrado, primero se verifica la firma (preferiblemente con un método de comparación de tiempo constante).
Ejemplo
Ver también:
hash_equals()
Hash
Debe evitarse en la medida de lo posible almacenar una contraseña reversible en su base de datos; solo desea verificar la contraseña en lugar de conocer su contenido. Si un usuario pierde su contraseña, es mejor permitirle restablecerla en lugar de enviarle la original (asegúrese de que el restablecimiento de contraseña solo se pueda realizar por un tiempo limitado).
La aplicación de una función hash es una operación unidireccional; posteriormente, se puede utilizar de forma segura para la verificación sin revelar los datos originales; para las contraseñas, un método de fuerza bruta es un enfoque factible para descubrirlo debido a su longitud relativamente corta y a la mala elección de contraseñas de muchas personas.
Se crearon algoritmos de hash como MD5 o SHA1 para verificar el contenido del archivo con un valor de hash conocido. Están muy optimizados para hacer esta verificación lo más rápido posible sin dejar de ser precisa. Dado su espacio de salida relativamente limitado, fue fácil construir una base de datos con contraseñas conocidas y sus respectivas salidas hash, las tablas de arco iris.
Agregar una sal a la contraseña antes de aplicar el hash haría inútil una tabla de arco iris, pero los avances recientes del hardware hicieron que las búsquedas de fuerza bruta fueran un enfoque viable. Es por eso que necesita un algoritmo hash que sea deliberadamente lento y simplemente imposible de optimizar. También debería poder aumentar la carga para un hardware más rápido sin afectar la capacidad de verificar los hashes de contraseñas existentes para que estén a prueba de futuro.
Actualmente hay dos opciones populares disponibles:
Esta respuesta usará un ejemplo con bcrypt.
Generacion
Se puede generar un hash de contraseña así:
La sal se genera con
openssl_random_pseudo_bytes()
para formar una masa aleatoria de datos que luego se procesabase64_encode()
ystrtr()
coincide con el alfabeto requerido de[A-Za-z0-9/.]
.La
crypt()
función realiza el hash basado en el algoritmo ($2y$
para Blowfish), el factor de costo (un factor de 13 toma aproximadamente 0.40s en una máquina de 3GHz) y la sal de 22 caracteres.Validación
Una vez que haya obtenido la fila que contiene la información del usuario, valide la contraseña de esta manera:
Para verificar una contraseña,
crypt()
vuelve a llamar pero pasa el hash calculado previamente como el valor de sal. El valor de retorno produce el mismo hash si la contraseña dada coincide con el hash. Para verificar el hash, a menudo se recomienda utilizar una función de comparación de tiempo constante para evitar ataques de tiempo.Hash de contraseña con PHP 5.5
PHP 5.5 introdujo las funciones de hash de contraseñas que puede utilizar para simplificar el método anterior de hash:
Y verificando:
Ver también:
password_hash()
,password_verify()
fuente
$iv_size = 16;
, usaría:$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC"))
para indicar el vínculo entre el tamaño de iv para usar con el cifrado utilizado. También puede expandir un poco la necesidad (o no) depkcs7_pad()
/pkcs7_unpad()
, o simplemente simplificar la publicación eliminándolos y usando "aes-256-ctr". Gran publicación @ Ja͢ckCreo que esto ha sido respondido antes ... pero de todos modos, si desea cifrar / descifrar datos, no puede usar SHA256
fuente
Respuesta Antecedentes y explicación
Para comprender esta pregunta, primero debe comprender qué es SHA256. SHA256 es una función hash criptográfica . Una función hash criptográfica es una función unidireccional, cuya salida es criptográficamente segura. Esto significa que es fácil calcular un hash (equivalente a encriptar datos), pero difícil obtener la entrada original usando el hash (equivalente a desencriptar los datos). Dado que el uso de una función hash criptográfica significa que el descifrado no es factible computacionalmente, por lo tanto, no puede realizar el descifrado con SHA256.
Lo que desea utilizar es una función bidireccional, pero más específicamente, un cifrado en bloque . Una función que permite tanto el cifrado como el descifrado de datos. Las funciones
mcrypt_encrypt
ymcrypt_decrypt
por defecto utilizan el algoritmo Blowfish. El uso de PHP de mcrypt se puede encontrar en este manual . También existe una lista de definiciones de cifrado para seleccionar el cifrado que utiliza mcrypt. Se puede encontrar una wiki sobre Blowfish en Wikipedia . Un cifrado de bloques cifra la entrada en bloques de tamaño y posición conocidos con una clave conocida, de modo que los datos se puedan descifrar posteriormente utilizando la clave. Esto es lo que SHA256 no puede proporcionarle.Código
fuente
Aquí hay un ejemplo usando openssl_encrypt
fuente
mcrypt_create_iv()
, usaría:, deopenssl_random_pseudo_bytes(openssl_cipher_iv_length($encryptionMethod))
esta manera la metodología funciona para cualquier valor de $ encryptionMethod y solo usaría la extensión openssl.false
paraopenssl_decrypt()
. Consulte stackoverflow.com/q/41952509/1066234 Dado que los cifrados de bloque como AES requieren que los datos de entrada sean un múltiplo exacto del tamaño del bloque (16 bytes para AES), es necesario el relleno.fuente
Me tomó bastante tiempo descubrir cómo no obtener un
false
al usaropenssl_decrypt()
y cómo encriptar y desencriptar funciona.Si desea pasar la cadena cifrada a través de una URL, debe codificar la cadena:
Para comprender mejor lo que está sucediendo, lea:
Para generar claves de 16 bytes de longitud, puede utilizar:
Para ver los mensajes de error de openssl puede utilizar:
echo openssl_error_string();
Espero que ayude.
fuente