Las otras respuestas ya dicen No, "roll your own" is rarely a good password storage scheme and yours is no exception.
Me gustaría agregar: tampoco es un buen esquema para almacenar / comunicar el nombre de usuario.
Básicamente eres hash. No hay nada de malo en eso, excepto:
- Estás usando una función que no está diseñada como una función hash segura. Al ser un cifrado, seguramente se encuentra en el extremo "seguro" de la escala, pero el hash también implica evitar colisiones de hash. Un cifrado no suele estar optimizado para no tener colisión. Se sabe que las almohadillas de una sola vez son irrompibles, porque tienen el número máximo de colisiones. Por lo tanto, un cifrado fuerte genera un hash pobre en términos de colisiones.
- Si almacena el nombre de usuario y el nombre de usuario cifrado con contraseña, existen más vulnerabilidades:
- En este caso, si su base de datos es hackeada, el atacante no solo obtendrá
the username encrypted with an unknown password
. También obtiene el texto claro aka. nombre de usuario Así que es un análisis de texto claro, que para algunas cifras es mucho más fácil que la fuerza bruta.
- Colisiones de hash: el atacante no necesita conocer la contraseña , sino cualquiera que produce el mismo cifrado para un texto breve y claro. Esto podría ser incluso más fácil que el análisis de texto claro.
- Si no almacena el nombre de usuario pero confía en un solo valor de transmisión combinado, todavía hay inconvenientes:
- En este caso, probablemente no consideraste las colisiones de hash. ¿Qué pasa con dos usuarios, que tienen el mismo nombre de usuario? ¿Qué pasa con dos idiotas, que tienen el mismo nombre de usuario y la misma contraseña? ¿Qué pasa con las colisiones hash de diferentes nombres de usuario y contraseñas por pura casualidad (recuerde: los cifrados no están optimizados para evitar colisiones)?
- En cualquier caso, existe el ataque "Pasar el hash": la comunicación de la red de rastreo de un atacante puede simplemente emular su aplicación para pasar los mismos datos que el usuario. ¿Hiciste algo al respecto? Si no es así, es por eso que no debes "rodar los tuyos".
Muchas veces, el protocolo de transmisión es tan importante para la seguridad como una función criptográfica sólida, independiente del hash en lugar del cifrado. Un protocolo incorrecto puede exponer su función a ataques para los que no es adecuado, especialmente "ataques de canal lateral" como "pasar el hash" o "hombre en el medio" que están evitando el análisis criptográfico real en el lado del atacante.
El esquema de almacenamiento de su contraseña puede ser propenso a tales ataques, porque no especificó si el nombre de usuario también se almacena en texto sin cifrar. Si lo hace, expone su esquema a los ataques descritos anteriormente. No almacenarlo en texto claro puede requerir un protocolo de transmisión propenso a ataques como se describe anteriormente.
Aquí hay algunas ideas adicionales sobre los protocolos de transmisión en su caso, ligeramente generalizadas:
Si no hiciste nada por el ataque "pasa el hash", entonces tu esquema es peor que muchos otros. Un atacante no necesita hackear su base de datos ni descifrar su cifrado. Obtiene lo que necesita de forma gratuita mediante el rastreo del tráfico de red.
HTTPS puede ser suficiente, aunque puede ser resuelto por "man in the middle": los usuarios no están buscando certificados de autenticación, ¿verdad? Un atacante simplemente abre una conexión no autenticada pero encriptada a su usuario y lo que sea que se espera que lo haga.
Un esquema adicional de desafío-respuesta puede agregar seguridad. Antes de iniciar sesión, el cliente recibe una cadena aleatoria única (desafío) que debe incluir en el hash (respuesta). Un atacante no podría reutilizar un hash rastreado, porque el desafío tampoco se reutiliza.
Pero, de nuevo, no es necesario "rodar".