Referencia – Validación de contraseña

Muy a menudo, las preguntas (especialmente las expresiones regulares etiquetadas) solicitan formas de validar las contraseñas. Parece que los usuarios suelen buscar métodos de validación de contraseñas que consisten en garantizar que una contraseña contenga caracteres específicos, coincida con un patrón específico y / o obedezca un recuento mínimo de caracteres. Esta publicación está destinada a ayudar a los usuarios a encontrar los métodos adecuados para la validación de contraseñas sin disminuir en gran medida la seguridad.

Entonces la pregunta es: ¿cómo se deben validar correctamente las contraseñas?

¿Por qué las reglas de validación de contraseñas son malas?

Nuestro propio Jeff Atwood (bloguero de Coding Horror y cofundador de Stack Overflow y Stack Exchange) escribió un blog sobre reglas de contraseñas en marzo de 2017 titulado Password Rules are Bullshit . Si no ha leído esta publicación, le insto a que lo haga, ya que refleja mucho la intención de esta publicación.

Si nunca ha oído hablar del NIST (Instituto Nacional de Estándares y Tecnología) , entonces probablemente no esté usando los métodos correctos de ciberseguridad para sus proyectos. En ese caso, revise sus Pautas de identidad digital . También debe mantenerse al día sobre las mejores prácticas para la ciberseguridad. La publicación especial NIST 800-63B (revisión 3) menciona lo siguiente sobre las reglas de contraseña:

Los verificadores NO DEBERÍAN imponer otras reglas de composición (por ejemplo, requerir mezclas de diferentes tipos de caracteres o prohibir caracteres repetidos consecutivamente) para secretos memorizados.

Incluso la documentación de Mozilla sobre la validación de datos del formulario se burla de las reglas de contraseña:

“Su contraseña debe tener entre 8 y 30 caracteres y contener una letra mayúscula, un símbolo y un número” (¿en serio?)

¿Qué sucede si impone reglas de composición para sus contraseñas? Está limitando la cantidad de contraseñas potenciales y eliminando las permutaciones de contraseña que no coinciden con sus reglas. ¡Esto permite a los piratas informáticos asegurar que sus ataques hagan lo mismo! “Ya, pero hay como un cuatrillón (1,000,000,000,000,000 o 1×10 15 ) permutaciones de contraseñas” : el clúster de 25 GPU rompe todas las contraseñas estándar de Windows en <6 horas (95 8 = 6,634,204,312,890,625 ~ 6.6×10 15 contraseñas).

xkcd

¿Cómo valido las contraseñas?

1. No crees tu propia autenticación

Deje de requerir contraseñas por completo , y permita que las personas inicien sesión con Google, Facebook, Twitter, Yahoo o cualquier otra forma válida de licencia de conducir de Internet con la que se sienta cómodo. La mejor contraseña es una que no tienes que almacenar .

Fuente: Tu contraseña es demasiado corta por Jeff Atwood.

2. Creando tu propia autenticación

Si realmente debe crear sus propios métodos de autenticación, al menos siga los métodos probados de ciberseguridad. Las siguientes dos secciones (2.1 y 2.2) están tomadas de la publicación actual del NIST , sección 5.1.1.2 Verificadores secretos memorizados .

2.1. Seguir los métodos de ciberseguridad PROBADA

NIST establece que DEBERÍA :

  • Requiere secretos memorizados elegidos por el suscriptor para tener al menos 8 caracteres de longitud.
    • Jeff Atwood propone que las contraseñas deben tener un mínimo de 10 caracteres para usuarios normales y un mínimo de 15 caracteres para usuarios con mayores privilegios (es decir, administradores y moderadores).
  • Permitir secretos memorizados elegidos por el suscriptor de hasta 64 caracteres o más de longitud.
    • Idealmente, ni siquiera deberías poner un límite superior en esto.
  • Permitir todas las impresiones ASCII (incluido el carácter de espacio) y Unicode.
    • A los efectos de los requisitos de longitud, cada punto de código Unicode DEBE contar como un solo carácter.
  • Compare los secretos posibles con una lista que contenga valores que se sabe que son comúnmente utilizados, esperados o comprometidos. Por ejemplo:
    • Contraseñas obtenidas de corpúsculos de violación anteriores.
    • Palabras del diccionario
    • Caracteres repetitivos o secuenciales (por ejemplo, aaaaaa , 1234abcd )
    • Palabras específicas del contexto, como el nombre del servicio, el nombre de usuario y sus derivados.
  • Ofrezca orientación al suscriptor, como un medidor de potencia de contraseña.
  • Implemente un mecanismo de limitación de velocidad que efectivamente limite el número de bashs de autenticación fallidos que se pueden realizar en la cuenta del suscriptor (consulte Límite de velocidad (limitación) ).
  • Forzar un cambio si hay evidencia de compromiso del autenticador.
  • Permita que los reclamantes utilicen la función pegar cuando ingresen un secreto memorizado (facilita el uso de administradores de contraseñas, lo que generalmente aumenta la probabilidad de que los usuarios elijan secretos memorizados más fuertes).

2.2. ¡NO use ninguno de los métodos en esta sección!

La misma publicación también establece que NO DEBERÍA :

  • Truncar el secreto
  • Permitir que el suscriptor almacene una pista que sea accesible para un reclamante no autenticado.
  • Indique a los suscriptores que utilicen tipos de información específicos (por ejemplo, “¿Cuál era el nombre de su primera mascota?”) Al elegir secretos memorizados.
  • Imponer otras reglas de composición (por ejemplo, requerir mezclas de diferentes tipos de caracteres o prohibir caracteres repetidos consecutivamente) para secretos memorizados.
  • Requiere que los secretos memorizados sean cambiados arbitrariamente (ej. Periódicamente).

Hay una gran cantidad de sitios web que explican cómo crear formularios de validación de contraseña “adecuados” : la mayoría de estos están desactualizados y no deben utilizarse.

3. Usando contraseña entropía

Antes de continuar leyendo esta sección, tenga en cuenta que la intención de esta sección no es brindarle las herramientas necesarias para implementar su propio esquema de seguridad , sino brindarle información sobre cómo los métodos de seguridad actuales validan las contraseñas. Si está considerando crear su propio esquema de seguridad, realmente debería pensarlo tres veces y leer este artículo de la comunidad de seguridad de StackExchange.

3.1. Descripción general de Password Entropy

En el nivel más básico, la entropía de contraseñas se puede calcular con la siguiente fórmula:

E = log2 (R ^ L)

En la fórmula anterior:

  • mi representa la entropía de la contraseña
  • R es la cantidad de caracteres en el conjunto de caracteres únicos
  • L es el número de caracteres en la contraseña

Esto significa que R ^ L representa la cantidad de contraseñas posibles; o, en términos de entropía, la cantidad de bashs necesarios para agotar todas las posibilidades.

Desafortunadamente, lo que esta fórmula no considera son cosas como:

  • Contraseñas genéricas: es decir, Password1 , admin
  • Nombres: es decir, John , Mary
  • Palabras de uso común: es decir, en el idioma inglés, I
  • Palabras invertidas / invertidas: es decir, drowssap (contraseña al revés)
  • Sustitución de letras (aka leet): es decir, P@$$w0rd

Agregar lógica para estas consideraciones adicionales presenta un gran desafío. Consulte 3.2 para conocer los paquetes existentes que puede agregar a sus proyectos.

3.2. Proyectos existentes de Password Entropy

En el momento de escribir esto, la biblioteca existente más conocida para estimar la fortaleza de la contraseña es zxcvbn por Dropbox (un proyecto de código abierto en GitHub). Se ha adaptado para admitir .net angularjs c c # c ++ ir a java javascript objective-c ocaml php python rest ruby moho scala


Haciéndolo de la manera incorrecta

Entiendo, sin embargo, que todos tienen diferentes requisitos y que a veces las personas quieren hacer las cosas mal. Para aquellos de ustedes que se ajustan a este criterio (o no tienen otra opción y han presentado todo lo que está por encima de esta sección y más a su gerente, pero se niegan a actualizar sus métodos), al menos permiten caracteres Unicode. En el momento en que limita los caracteres de la contraseña a un conjunto específico de caracteres (es decir, para asegurar que exista un carácter ASCII en minúscula o especificar los caracteres que el usuario puede o no puede ingresar !@#$%^&*() ), Solo está solicitando ¡problema!

PD Nunca confíes en la validación del lado del cliente, ya que puede ser deshabilitada fácilmente. Eso significa para aquellos de ustedes que intentan validar contraseñas usando javascript STOP . Ver JavaScript: validación del lado del cliente vs. lado del servidor para más información.

El siguiente patrón de expresión regular no funciona en todos los lenguajes de progtwigción, pero sí en muchos de los principales lenguajes de progtwigción ( java .net php perl ruby ). Tenga en cuenta que la siguiente expresión regular puede no funcionar en su idioma (o incluso en su versión de idioma) y es posible que necesite utilizar alternativas (es decir, python : consulte las propiedades Unicode de Python Regex ). Algunos lenguajes de progtwigción incluso tienen mejores métodos para verificar este tipo de cosas (es decir, usar el complemento de validación de contraseña para mysql ) en lugar de reinventar la rueda. Al usar node.js, lo siguiente es válido si se usa el complemento XRegExp o alguna otra herramienta de conversión para las clases Unicode, como se explica en las expresiones regulares JavaScript + Unicode .

Si necesita evitar que se ingresen caracteres de control, puede avisar al usuario cuando se produce una coincidencia de expresiones regulares utilizando el patrón [^\P{C}\s] . Esto SÓLO coincidirá con los caracteres de control que no sean también espacios en blanco, es decir, pestaña horizontal, avance de línea, pestaña vertical.

La siguiente expresión regular asegura que al menos una letra minúscula, mayúscula, un número y un símbolo existen en una contraseña de más de 8 caracteres:

 ^(?=\P{Ll}*\p{Ll})(?=\P{Lu}*\p{Lu})(?=\P{N}*\p{N})(?=[\p{L}\p{N}]*[^\p{L}\p{N}])[\s\S]{8,}$ 
  • ^ Posición de confirmación al comienzo de la línea.
  • (?=\P{Ll}*\p{Ll}) Asegúrese de que exista al menos una letra minúscula (en cualquier secuencia de comandos).
  • (?=\P{Lu}*\p{Lu}) Asegúrese de que exista al menos una letra mayúscula (en cualquier secuencia de comandos).
  • (?=\P{N}*\p{N}) Asegúrese de que exista al menos un carácter numérico (en cualquier secuencia de comandos).
  • (?=[\p{L}\p{N}]*[^\p{L}\p{N}]) Asegúrese de que al menos uno de los caracteres (en cualquier script) no sea una letra o un dígito existe
  • [\s\S]{8,} Coincide con cualquier personaje 8 o más veces.
  • $ Posición de confirmación al final de la línea.

Utilice la expresión regular anterior según su propio criterio. ¡Usted ha sido advertido!