En primer lugar, no te preocupes por el nombre de usuario. Se supone que el nombre de usuario es información pública. Si no lo fuera, no sería un nombre de usuario, sería una contraseña. Simplemente asuma que un atacante podrá averiguar el (los) nombre (s) de usuario en cualquier caso y diseñe su sistema para que esté seguro con esa suposición.
En segundo lugar, no te preocupes si el método de cifrado (o hashing, etc.) sea público, tampoco. Eso es principio de Kerckhoff : el método de encriptación debe tratarse como público, lo único que debe ser secreto debe ser el clave (o contraseña, en este caso).
Hay muchas buenas razones para esto, entre ellas el hecho de que le permite publicar cómo funciona el sistema (y, por lo tanto, convencer a sus usuarios de que es seguro, o pedir ayuda a expertos en seguridad, o simplemente usar un sistema estándar diseñado y analizado por dichos expertos) sin comprometer su seguridad.
En tercer lugar, no te preocupes por la salt tampoco. La sal también debe ser tratada como (potencialmente) conocimiento público. Su propósito no es proporcionar ningún secreto adicional, sino protegerse contra los ataques que utilizan tablas hash precompiladas asegurando que la contraseña de cada usuario se marque de forma diferente, incluso si las contraseñas reales son las mismas.
Bien, entonces, ¿qué debería hacer?
En primer lugar, debe usar una función de derivación de claves segura que implementa key estiramiento (y salazón, por supuesto) para derivar la clave de cifrado del usuario a partir de su contraseña. PBKDF2 debería hacerlo bien, aunque, por ejemplo, scrypt puede ser aún mejor si lo tiene disponible.
En segundo lugar, obviamente, no deberías no usar la clave de cifrado como el hash de la contraseña. De hecho, no debe almacenar nada en su base de datos que pueda usarse para obtener la clave de cifrado sin saber la contraseña. (Por ejemplo, la clave de cifrado no debe ser un hash del hash de la contraseña).
Una cosa que podría hacer es derivar la clave de cifrado y el hash de la contraseña por separado de la contraseña utilizando PBKDF2, pero eso sería un poco ineficiente, ya que PBKDF2 es deliberadamente lento. En su lugar, podría derivar la clave de cifrado de la contraseña con PBKDF2, y luego usar un hash criptográfico normal (por ejemplo, SHA-256) de la clave como el hash de la contraseña para iniciar sesión. (O, si desea tener más cuidado, obtenga tanto la clave de cifrado como el hash de contraseña de una clave intermedia derivada de la contraseña utilizando PBKDF2.)
Finalmente, para facilitar el cambio de contraseña, no encripta directamente los archivos con la clave de encriptación del usuario. En su lugar, para cada archivo, cree una clave de archivo aleatoria, cifre el archivo con la clave de archivo y cifre la clave de archivo con la clave de cifrado del usuario. De esa manera, cuando el usuario desea cambiar su contraseña, solo necesita volver a cifrar las claves de archivo.