Se pueden realizar varias mejoras a las funciones que ha asignado, según mi conocimiento.
Amenazas obvias
Primero, y lo más importante, mantenga segura su clave privada , y haga que sea externa a la definición de la función (por ejemplo, un segundo argumento). Recomendaría hacer un esfuerzo significativo para resolver este problema. ¿Es este cifrado por usuario o el cifrado de toda la aplicación? Si es por usuario, ¿por qué no usar un algoritmo de derivación de claves, como PBKDF2 ? Si es de toda la aplicación, buena suerte con el almacenamiento seguro: lo he pensado antes y no parece trivial para una aplicación web típica. Solo asegúrese de que no almacene la clave privada junto con la fuente, ni (obviamente) en la misma base de datos .
Además, aparte, nunca uses cifrado simétrico para nada que sea como una contraseña. Utilice un hash unidireccional en su lugar. Supongo, para esta respuesta, que realmente necesitas recuperar la clave del CD original, en lugar de solo verificar una coincidencia.
Segundo, tengo dudas sobre el uso de MCRYPT_RAND. Parece que podría ser el mismo PRNG que rand () , que no es ideal. Generar el IV con MCRYPT_DEV_URANDOM es lo que recomendaría: / dev / random y / dev / urandom se consideran fuentes de primera clase de números aleatorios criptográficos en sistemas basados en Unix. Tenga en cuenta que no generalmente desea usar / dev / random para una aplicación web, ya que abriría un vector DoS fácil - y / dev / urandom debería ser suficiente fuera de los entornos integrados, de todos modos.
Otros problemas de implementación
Ahora, con las principales vulnerabilidades que puedo detectar, algunos detalles más detallados:
Estás mezclando las funciones OpenSSL y mcrypt. Además, openssl_encrypt no está documentado en los documentos oficiales de PHP (aunque sospecho que está documentado para C en algún lugar, sin embargo ...). Podría ser mejor usar mcrypt_encrypt , ya que está documentado explícitamente para PHP.
También estás mezclando CAST-256 y AES-256. Probablemente debería quedarse con AES-256 en todo momento, ya que ese es el algoritmo estándar generalmente recomendado para un cifrado simétrico sólido. Tenga en cuenta que AES-256 es MCRYPT_RIJNDAEL_128 utilizado con una clave de 256 bits , y NO es lo mismo que Rijndael-256, que es algo que no me había dado cuenta (¡cuanto más sabes!).
No estoy seguro de cuál es el modo de cifrado preferido, pero al menos CBC es uno que he visto recomendado para AES. Esperemos que alguien más tenga alguna entrada.