La debilidad en su sistema es intrínseca: no hay sal real. Por sus comentarios, supongo que no puede (por alguna razón contextual) almacenar un archivo sal generado aleatoriamente. Entonces, lo que haces equivale, básicamente, a usar el par "usuario + sitio" como sal.
Sus diversos hash son complejos y algunas partes son inútiles: no es necesario ingresar la contraseña en tantos lugares. Debes esforzarte por la simplicidad; La complejidad es tu enemigo. Aún así, tiene que lidiar con la idiosincrasia de PBKDF2 (si desea usar esa función), por lo que lo siguiente debería ser lo más seguro posible:
s = SHA-256(username + '|' + sitename)
p = SHA-256(password)
hash = PBKDF2(p, s, rounds)
Tenga en cuenta que uso un '|' carácter como separador, y asumo que tal carácter no aparece en el nombre del sitio (esto es para evitar colisiones falsas). El SHA-256 adicional en la contraseña es solo para evitar un problema de PBKDF2, que es que se vuelve dos veces más lento cuando la longitud de la contraseña excede la longitud de la función hash subyacente (64 bytes para SHA-1 y SHA-256). Si está seguro de que sus contraseñas nunca excederán los 64 bytes, puede eliminar el segundo hash y usar la "contraseña" directamente en PBKDF2.
Principal problema restante: si el usuario cambia su contraseña, la nueva contraseña y la contraseña antigua usarán el mismo pseudo-sal. Si un atacante puede obtener ambos valores hash, entonces puede intentar romper ambos por el costo de romper solo uno. Se produce un problema similar si destruye una cuenta de usuario y luego reutiliza el mismo nombre de usuario. No puede evitar este problema mientras no almacene un valor similar a la sal (generado aleatoriamente) junto con los valores hash.
Mejoras: es posible que desee cambiar algunos parámetros. Por ejemplo, si su servidor es una PC (de 64 bits, o al menos una PC con SSE2 y utiliza OpenSSL para la implementación de la función hash), es posible que desee asegurarse de que PBKDF2 dependa de SHA-512 en lugar de SHA-256 o SHA-1: SHA-512 será eficiente en su PC, pero le hará la vida más difícil a un atacante con una GPU (la GPU habitual se siente menos cómoda con los tipos enteros de 64 bits). También puede considerar cambiar de PBKDF2 a Bcrypt, por las razones expuestas allí .