Cifrado bidireccional en PHP

Mi aplicación (obviamente) usa una identificación única para distinguir los registros. Este UID se transmite en las URL (por ejemplo, ./examplepage.php?UID=$example_int ), entre otras cosas.

Si bien obviamente tengo validada la parte del servidor para asegurarme de que los clientes no acceden a los datos de otros clientes, ¿hay un método de encriptación de dos vías que pueda usar en PHP para pasar solo los UID encriptados (por ej., ./examplepage.php?EUID=$encrypted_int ), para reducir aún más la posibilidad de que alguien piense “hey, ¿qué pasa si incremente este entero?”

TIA.

Colocar un hash al lado de la ID para garantizar su seguridad, o rellenar la ID con datos adicionales, o incluso convertir la ID en hexadecimal, todo funcionaría bastante bien, creo.

PHP 5.3 ha introducido un nuevo método de encriptación que es realmente fácil de usar: openssl_encrypt y openssl_decrypt . No está bien documentado aquí, así que aquí hay un ejemplo simple:

 $textToEncrypt = "My super secret information."; $encryptionMethod = "AES-256-CBC"; // AES is used by the US gov't to encrypt top secret documents. $secretHash = "25c6c7ff35b9979b151f2136cd13b0ff"; //To encrypt $encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash); //To Decrypt $decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash); //Result echo "Encrypted: $encryptedMessage 
Decrypted: $decryptedMessage";

Elegí 256-AES porque es sólido y rápido. Ha sido adoptado por el gobierno de los Estados Unidos para encriptar documentos secretos. Es rápido considerando la máquina y el software. Aquí hay una lista de métodos de encriptación disponibles:

AES-128-CBC, AES-128-CFB, AES-128-CFB1, AES-128-CFB8, AES-128-ECB, AES-128-OFB, AES-192-CBC, AES-192-CFB, AES- 192-CFB1, AES-192-CFB8, AES-192-ECB, AES-192-OFB, AES-256-CBC, AES-256-CFB, AES-256-CFB1, AES-256-CFB8, AES-256- BCE, AES-256-OFB, BF-CBC, BF-CFB, BF-ECB, BF-OFB, CAMELLIA-128-CBC, CAMELLIA-128-CFB, CAMELLIA-128-CFB1, CAMELLIA-128-CFB8, CAMELLIA- 128-ECB, CAMELLIA-128-OFB, CAMELLIA-192-CBC, CAMELLIA-192-CFB, CAMELLIA-192-CFB1, CAMELLIA-192-CFB8, CAMELLIA-192-ECB, CAMELLIA-192-OFB, CAMELLIA-256- CBC, CAMELLIA-256-CFB, CAMELLIA-256-CFB1, CAMELLIA-256-CFB8, CAMELLIA-256-ECB, CAMELLIA-256-OFB, CAST5-CBC, CAST5-CFB, CAST5-ECB, CAST5-OFB, DES- CBC, DES-CFB, DES-CFB1, DES-CFB8, DES-ECB, DES-EDE, DES-EDE-CBC, DES-EDE-CFB, DES-EDE-OFB, DES-EDE3, DES-EDE3-CBC, DES-EDE3-CFB, DES-EDE3-CFB1, DES-EDE3-CFB8, DES-EDE3-OFB, DES-OFB, DESX-CBC, RC2-40-CBC, RC2-64-CBC, RC2-CBC, RC2- CFB, RC2-ECB, RC2-OFB, RC4, RC4-40, SEED-CBC, SEED-CFB, SEED-ECB, SEED-OFB, aes-128-cbc, aes-128-cfb, aes-128-cfb1, aes-1 28-cfb8, aes-128-ecb, aes-128-ofb, aes-192-cbc, aes-192-cfb, aes-192-cfb1, aes-192-cfb8, aes-192-ecb, aes-192- ofb, aes-256-cbc, aes-256-cfb, aes-256-cfb1, aes-256-cfb8, aes-256-ecb, aes-256-ofb, bf-cbc, bf-cfb, bf-ecb, bf-ofb, camelia-128-cbc, camelia-128-cfb, camelia-128-cfb1, camelia-128-cfb8, camelia-128-ecb, camelia-128-ofb, camelia-192-cbc, camelia-192- cfb, camelia-192-cfb1, camelia-192-cfb8, camelia-192-ecb, camelia-192-ofb, camelia-256-cbc, camelia-256-cfb, camelia-256-cfb1, camelia-256-cfb8, camelia-256-ecb, camelia-256-ofb, cast5-cbc, cast5-cfb, cast5-ecb, cast5-ofb, des-cbc, des-cfb, des-cfb1, des-cfb8, des-ecb, des- ede, des-ede-cbc, des-ede-cfb, des-ede-ofb, des-ede3, des-ede3-cbc, des-ede3-cfb, des-ede3-cfb1, des-ede3-cfb8, des- ede3-ofb, des-ofb, desx-cbc, rc2-40-cbc, rc2-64-cbc, rc2-cbc, rc2-cfb, rc2-ecb, rc2-ofb, rc4, rc4-40, semilla-cbc, seed-cfb, seed-ecb, seed-ofb


¡¡¡ACTUALIZACIÓN IMPORTANTE!!!

Gracias a Hobo y Jorwin por señalar que en PHP 5.3.3> hay un nuevo parámetro que hace que esta función sea un poco más segura.

Jorwin hizo referencia a este enlace en su comentario , y aquí hay un extracto que es aplicable:

En 5.3.3 agregaron un nuevo parámetro, string $iv (vector de inicialización) Los parámetros reales son: string openssl_encrypt ( string $data , string $method , string $password, bool $raw_output = false, string $iv )

Si falta $iv , se emite una advertencia: “Usar un vector de inicialización vacío (iv) es potencialmente inseguro y no recomendado”.

Si $iv es demasiado corto, otra advertencia: “IV pasado tiene solo 3 bytes de largo, cifrado espera una IV de precisamente 8 bytes, relleno con \ 0”

el mismo IV se debe usar en openssl_decrypt()

No necesita cifrado bidireccional: el cifrado es para mantener el secreto , pero lo que realmente está buscando aquí es la autenticidad .

Los HMAC (esencialmente hashes codificados) son una forma de obtener autenticidad criptográfica. Acompañe el UID con un HMAC del UID (PHP tiene una implementación HMAC ), usando una clave que solo el servidor conoce. Al comienzo de cada solicitud, verifique el HMAC.

Básicamente, use la herramienta correcta para el trabajo correcto.

Si bien PHP admite muchos algoritmos hash bidireccionales, no creo que sea útil en este ejemplo. Lo que debes hacer es:

  1. Cargue la fila del almacenamiento con el ID proporcionado
  2. Compruebe que el propietario de la fila sea el usuario autenticado y, en caso de que no arroje una excepción, informe al usuario que no vuelva a hacerlo.

Pero si su corazón está configurado en hash simplemente elija uno de los algoritmos provistos .

Para el cifrado bidireccional , compruebe mcrypt , o si prefiere una implementación pura phpseclib .

En primer lugar, cifrar los parámetros de URL suele ser una mala idea , y una búsqueda separada (basada en una columna de índice de CHAR generada por un CSPRNG) es mejor para el 99,9% de los casos de uso.

Dicho esto: sí, puede usar la extensión OpenSSL ( no use mcrypt ) para encriptar los datos como sugirió espradley , sin embargo, le advierto que no se detenga solo en el cifrado.

El cifrado sin autenticación de mensajes es peligroso , especialmente si confía en un usuario final con el texto cifrado.

La solución, por lo tanto, es utilizar encriptación autenticada , a la que se puede acceder fácilmente con libsodium, disponible en PECL .

Si por alguna razón no puede instalar una extensión PECL, hay dos bibliotecas PHP para elegir: desactivar / php-encryption y zend-crypt . Ambos ofrecen cifrado autenticado compatible con los estándares y ambos son seguros de usar (por lo que vale, frecuentemente realizo auditorías de código para implementaciones de criptografía en PHP, no soy simplemente una persona aleatoria en Internet).