Por un lado, supongo que el sistema que está planeando es para un caso de uso limitado, ya que no creo que sea imposible exigir un poco más de las contraseñas en el uso general: incluso Stackexchange requiere ocho caracteres con números.
En cierto modo, un millón de códigos posibles es a la vez muy pequeño y lo suficientemente grande. Si un atacante obtiene su base de datos de contraseñas y puede intentar descifrar los hashes fuera de línea, desaparecerán en un instante. Incluso si el hashing fuera lo suficientemente lento como para permitir solo probar diez códigos por segundo, todo el espacio de teclas se completaría en un poco más de un día. No va a ser tan lento.
Por otra parte, ya que puede limitar los intentos de inicio de sesión en línea, debe ser bastante controlable. Para obtener solo un 1% de adivinar un código de acceso, el atacante necesitaría 10000 intentos. Eso no debería ser habitual, especialmente desde una IP de una sola fuente o contra una sola cuenta, y debe bloquear la fuente en ese momento y considerar bloquear la cuenta. (Si tienes muchos usuarios y eres atacado por una botnet, entonces es más difícil de detectar).
Aunque con códigos de dígitos, usted debe hacerlos aleatorios, en lugar de dejar que el usuario decida. De lo contrario, solo elegirán las fechas, haciendo que el espacio clave efectivo sea más pequeño. Ya has tocado esto cuando planificaste un reinicio aleatorio, pero para empezar tiene que ser aleatorio, de lo contrario, descubrir los cumpleaños de las personas será demasiado rentable.
En cuanto al cambio automático del PIN, heck no. Además del spam que otros han mencionado, también podría bloquear al usuario legítimo si no puede acceder a su correo electrónico en el momento adecuado. Y si lo hace no con limitación de velocidad, no tendrán tiempo para leer su correo electrónico antes de que el atacante haya realizado otros 20 intentos y el código vuelva a cambiar ... Entonces, nuevamente, si do limitante de velocidad, podría bloquear la cuenta a propósito durante un tiempo.
Por supuesto, el bloqueo de cuentas es un vector de DoS, pero es un compromiso que debe elegir. ¿Quieres priorizar el bloqueo de los malos o asegurarte de que entren los buenos?
¿El cambio automático haría que el código sea más difícil de adivinar? Bueno, sí, marginalmente. Para un código de acceso invariable, tendría K en N posibilidad de adivinarlo, al hacer K adivina contra N códigos posibles. Para un código cambiante, la posibilidad de adivinar es una constante 1 / N para cada estimación, o 1- (1-1 / N) ^ K para K estimaciones. Calcula alrededor de 500000 contra 700000 para una probabilidad del 50% de hacerlo bien. Es más, pero en la misma escala. ¿Desea permitir esos cien mil intentos de inicio de sesión en primer lugar?