2009-09-07 16 views
28

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

Aunque evidentemente tengo una validación del lado del servidor para asegurarme de que los clientes no accedan a los datos de otros clientes, ¿hay un método de encriptación bidireccional que pueda usar en PHP para pasar UIDs cifrados (por ejemplo ./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.

+0

votaron en contra porque no creía que la conversación terminara siendo realmente sobre encriptación bidireccional ... –

Respuesta

-3

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

+2

Gracias, buena llamada al convertir a hexadecimal. – benjy

+0

Aunque no protegería a nadie con "conocimientos de tecnología" para probar el siguiente número hexadecimal. Estás cambiando bases, el problema "potencial" permanece. – rogeriopvl

+5

@benjy cualquiera que tenga la iniciativa de incrementar el UID, reconocerá de inmediato un hexágono o int acolchado. Deberías estar haciendo lo que @caf sugirió. O solo generando UID no incrementales y no predecibles. – bucabay

3

Si bien PHP admite muchos algoritmos hash bidireccionales, no lo veo útil en este ejemplo. Lo que hay que hacer es:

  1. Cargar la fila de almacenamiento mediante la identificación proporcionada
  2. Comprobar que el propietario de la fila es el usuario autenticado y si no es una excepción e informar al usuario que no lo haga de nuevo

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

+0

Gracias por la sugerencia. De hecho, ya estoy haciendo eso, pero solo quería una forma más de disuadir a los usuarios de jugar con ese valor. – benjy

+0

Claro. Por lo general, no me preocupo por cosas así. Hay poco daño que un usuario puede hacer al jugar con los identificadores si tienes las ACL correctas en su lugar. –

+0

¿no sería el 2do paso el primero en ser más eficiente? –

27

que no es necesario el cifrado de dos vías - cifrado es el secreto para mantener , pero lo que realmente está buscando aquí es autenticidad.

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

Básicamente, utilice la herramienta adecuada para el trabajo correcto.

+0

ESTO REQUIERE UN CAMPO DB ADICIONAL. Estoy de acuerdo con esto, pero esto requiere almacenarlo en un campo adicional. –

+0

@AlexV: No, porque el servidor puede recalcular el HMAC cuando recibe una solicitud. – caf

85

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í está un ejemplo sencillo:

$textToEncrypt = "My super secret information."; 
$encryptionMethod = "AES-256-CBC"; // AES is used by the U.S. 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 <br>Decrypted: $decryptedMessage"; 

me eligió 256-AES porque es sólido y rápido. Ha sido adoptado por el gobierno de EE. UU. Para cifrar 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-ECB, 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- BCE, 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-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-ecb, aes-256-ofb, bf-cbc, bf-cfb, bf-ecb, bf-ofb, camelia-128-cbc, camelia-128-cfb, camellia-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, r C2-CFB, RC2-BCE, RC2-OFB, RC4, RC4-40, semilla-CBC, CFB-semilla, semilla-BCE, semilla-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 hace referencia en este enlace his comment, y aquí es un extracto que es aplicable:

En 5.3.3 se agregaron un nuevo parámetro, string $iv (inicialización vector) 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 es sólo 3 bytes de longitud, cifrado espera un IV precisamente de 8 bytes, relleno con \ 0"

misma IV se debe utilizar en openssl_decrypt()

+0

Usar esto como se muestra me da una advertencia "Usar un vector de inicialización vacío (iv) es potencialmente inseguro y no recomendado". ¿Es ese un nuevo parámetro? ¿Debería actualizarse esta respuesta? – Hobo

+2

@Hobo - Tienes razón, me encontré con el mismo problema. Esta es una explicación más detallada. Gracias espradley por la respuesta sin embargo. http://php.net/manual/en/function.openssl-encrypt.php#104438 – Joe

+0

@Jowin - absolutamente correcto. Estoy en php 5.2.2 pero a partir de 5.3.3 necesitarás pasar el 5º parámetro u obtener una advertencia. Es solo una advertencia para que no rompa la aplicación, por ejemplo, pero es definitivamente más seguro pasarla. – espradley

0

En primer lugar, encrypting URL parameters is usually a bad idea, y una búsqueda separada (basada en una columna de índice CHAR generada por un CSPRNG) es mejor para el 99,9% de los casos de uso.

Con eso dicho: Sí, puede usar la extensión de OpenSSL (don't use mcrypt) para encriptar los datos like espradley suggested, sin embargo, le advierto que no se detenga simplemente al cifrado.

Encryption without message authentication is dangerous, especialmente si confía en un usuario final con el texto cifrado.Por lo tanto, la solución es usar authenticated encryption, que se puede acceder fácilmente con libsodium, available on PECL.

Si no puede por alguna razón instalar una extensión PECL, hay dos bibliotecas PHP para elegir: defuse/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 code audits for cryptography implementations en PHP, no soy simplemente alguna persona al azar en Internet).