Validacion de token de forma Criptografica, evitar ataques CSRF
Bueno esto viene del tema que abrio el usuario MiguelCanellas
[Aporte]: Sistema Anti ataques CSRF (Espero sugerencias).
La forma mas sencilla de genera un token sin incluir nada de criptografia y que se envie al usuario para posteriormente ser validado es la siguiente:
Código
Esto nos produce una cadena hash sha256 apartir de 1Kilobyte de datos random.
La cosa seria sencilla guardarlo en la $_SESSION en el server y mandarlo al usuario, si lo devuelve comparamos que sean iguales y listo no hay mucho pierde.
Se necesita mas seguridad.... ?
El simple hecho que tengamos una cadena hash sha256 apartir de 1Kilobyte de datos random. hace casi imposible que alguien pueda generar el token por si solo y que coincida con el que generamos nosotros, podriamos incrementar la cantidad de bytes generados por la funcion openssl_random_pseudo_bytes simplemente incrementando su valor.
Ahora si realmente queremos proteger la informacion mediante criptografia tenemos que hacer las cosas bien.
Una implentacion rapida para ejemplificar este proceso es la siguiente:
Código
<?php $cipher = 'AES-256-CBC'; //SUIT de cirado utilizada $strkey = "s3cr3tk3yh4x0r"; //Clave en el servidor, secreta, cambiar esta clave de ejemplo POR FAVOR de preferencia utilizar una clave generada de forma segura con openssl_random_pseudo_bytes o /dev/random $ivlen = openssl_cipher_iv_length($cipher); // Obtenemos el tamaño del Vector Inicializado de acuardo a la Suit de cifrado que estemos utilizando $iv = openssl_random_pseudo_bytes($ivlen); // Obtenemos $ivlen bytes random no nos interesa saber su valor $token_cifrado = openssl_encrypt($token,$cipher,$realkey,OPENSSL_RAW_DATA,$iv); echo "token: ".$token."\n"; echo "token cifrado, salida raw: ".$token_cifrado ."\n"; echo "token cifrado, salida base64: ".$salida."\n"; $token_decifrado = openssl_decrypt($entrada,$cipher,$realkey,OPENSSL_RAW_DATA,$iv); echo "token decifrado: ".$token_decifrado ."\n"; if($token_decifrado == $token) { echo "token correcto\n"; } else { echo "token Incorrecto\n"; } ?>
Si vemos el codigo anterior el "token" que enviaremos al usuario es la salida en base64 del token previamente cifrado.
Acontinuacion una posible salida de las casi infinitas salidas....
Código:
token: 5ab8aac170554a2683e0cc0534a34e80d0f16031a13faa3c3a5ee44902b2c6a1
token cifrado, salida raw: CU?!,F8C4d1su
SN{|큮vDjUa=qQKKKȀE#(@/I
token cifrado, salida base64: AUO6plUB9j8h+IvsyixGOAfZQzRkCzG84XN1vN7X2Aq2CVNOont87YGudsJEq2q1VWE9vZhxqJWfUUviv0tL9ciA+kWTI74oGEAvl4sSSak=
token decifrado: 5ab8aac170554a2683e0cc0534a34e80d0f16031a13faa3c3a5ee44902b2c6a1
token correcto
La idea en este caso es enviar la informacion cifrada al usurio y cuando este la envie devuelta se descifra y se compara con la almacenada previamente en la $_SESSION del usuario.
Cosas que se pueden mejorar el valor de nuestra Key inicial podria ser un archivo random en nuestro servidor generado previamente, podriamos tener una llave distinta por usuario, etc etc etc...