¿Por qué las contraseñas generadas aleatoriamente suelen ser hexadecimales?

8

La mayoría de las veces, cuando veo una contraseña generada aleatoriamente, es hexadecimal, es decir, solo usa el conjunto de caracteres [0-9a-f] . ¿No sería mucho más seguro si el conjunto de caracteres fuera [0-9a-z] , y mucho menos [0-9a-zA-Z] ?

    
pregunta Duncan X Simpson 06.08.2017 - 02:14
fuente

4 respuestas

6

Arminius mencionó la simplicidad del hex, y creo que vale la pena expandirse.

Los generadores de números aleatorios generalmente funcionan en bits, por lo que el rango de números que pueden generar es una potencia de dos. Un rango de caracteres como [0-9a-zA-Z] tiene 62 caracteres, lo que equivale a una potencia de dos (64), por lo que la computadora tiene que hacer algunas conversiones entre los rangos.

Se puede hacer, pero es fácil hacerlo mal. La forma "estándar" es tomar el número real, dividirlo por el rango que desea y tomar el resto como su número aleatorio. Eso introduce un sesgo sin embargo. Para un ejemplo simple, supongamos que genera números en [0-3] pero que los quiere en [0-2] . El rango [0-3] se asignaría al rango [0-2] de la siguiente manera:

0 => 0 mod 3 => 0
1 => 1 mod 3 => 1
2 => 2 mod 3 => 2
3 => 3 mod 3 => 0

Observe cómo puede obtener un 0 de dos maneras diferentes: 0 y 3 ambos van a 0 . El enfoque está sesgado hacia la generación de 0 s, lo que hará que tu contraseña sea más fácil de adivinar.

La forma correcta consiste en calcular el relleno correcto para que lo que genera se ajuste de manera uniforme al rango, lo cual es complicado y potencialmente podría hacer que su contraseña sea mucho más larga dependiendo de cómo se compara su rango de salida con eso del generador de números aleatorios.

Un enfoque más fácil es usar un rango que ya es una potencia de dos para que pueda ignorar el sesgo por completo. La mayoría tiene problemas.

  • Base-2 (binario) produce cadenas extremadamente largas.
  • Base-4 (cuaternario) no es mucho mejor.
  • Base-8 (octal) es mejor pero aún es largo.
  • Base-16 (hex) es un poco largo, pero razonable. También codifica 4 bits por carácter, lo cual es bastante conveniente cuando las computadoras prefieren múltiplos de 8.
  • La base 32 codifica 5 bits por carácter, lo que no es conveniente si las computadoras prefieren múltiplos de 8.
  • La base 64 codifica 6 bits por carácter, lo cual es incómodo (pero un poco menos, ya que al menos es un número par).
  • La base 96 es popular, pero no tiene una potencia de 2, por lo que tiene el mismo problema que [0-9a-zA-Z] .
  • Base-128 y, sobre todo, símbolos que no se pueden escribir fácilmente en un teclado de consulta típico.

Para ampliar un poco sobre por qué la base-64 es un problema, considere qué sucede cuando intenta codificar un solo byte (8 bits). No puedes hacerlo con un solo carácter base-64 ya que solo obtiene 6 de los 8 bits. Pero si usa dos caracteres, debe descubrir cómo rellenar su byte de 8 bits en una salida de 12 bits sin introducir sesgos o sugerir que podría haber un byte adicional.

Hex, en contraste, es casi trivial para codificar bytes. Simplemente busque cada byte en una tabla de 256 elementos para obtener dos caracteres y escupirlos. Proporciona contraseñas razonablemente cortas, no usa símbolos extraños y es fácil de implementar. Es la mejor opción para generadores de contraseñas conscientes de la seguridad.

Quizás lo mejor de todo es que la mayoría de los lenguajes de programación admiten hexadecimales fuera de la caja. La biblioteca C tiene printf() , que puede formatearse como octal, decimal o hexadecimal. Del mismo modo, C ++ tiene manipuladores IO que utilizan los mismos formatos. Sin embargo, no hay soporte incorporado para otras bases (ni siquiera base-64), así que debes hacerlo tú mismo (complicado) o encontrar una biblioteca que lo haga correctamente (violar la regla NIH (y posiblemente también mucho trabajo para verificarla)). Es mucho más fácil simplemente usar lo que está en la biblioteca estándar, especialmente cuando funciona.

Es cierto que se obtiene menos seguridad por carácter con hexadecimal que con otras codificaciones, pero como Eric Lagergren señaló en los comentarios, hex(random_bytes) es tan seguro como solo random_bytes . Es solo que más tiempo es todo. De hecho, todo lo que necesita son 16 bytes (codificados como 32 dígitos hexadecimales) para tener una contraseña tan fuerte que cualquier atacante quemará toda la energía del sistema solar antes de que tengan una mínima posibilidad de adivinarlo. La mayoría de los sitios web aceptan con gusto contraseñas de 32 caracteres, por lo que no hay problemas para usarlas.

    
respondido por el Mirinth 06.08.2017 - 06:34
fuente
14

(¿Tiene pruebas de que las contraseñas aleatorias son usualmente hexadecimal?)

Estas son algunas de las posibles razones por las que frecuentemente encuentra contraseñas hexadecimales:

  • Es posible que las contraseñas que ves ya estén ocultas. Como las funciones hash devuelven cadenas binarias, a menudo las verá almacenadas en forma hexadecimal.

  • Hashear una secuencia binaria aleatoria (por ejemplo, desde /dev/urandom ) es una forma barata pero razonablemente segura de crear una contraseña aleatoria. De vez en cuando verás algo así en la naturaleza:

    $ head -c 100 /dev/urandom | sha256sum | head -c 25
    c9ea6b67af36753a68ef42429
    
  • Todos los caracteres son fáciles de distinguir. Es decir, no tendrá problemas al confundir 1 y I , O y 0 , etc. si solo permite hexadecimales en primer lugar.

  • Las secuencias generadas aleatoriamente suelen ser binarias, por lo que mostrarlas en forma hexadecimal parece lógico y eficiente.

Dicho esto, elegir una contraseña aleatoria de un rango mayor que [0-9a-f] es obviamente más seguro si no ajusta la longitud. Por lo general, sigo con tu sugerencia de [0-9a-zA-Z] , que me ofrece una amplia gama y evita caracteres especiales que pueden causar problemas con el almacenamiento y la transmisión.

También, aquí está lo que puse en mi configuración de shell para generar rápidamente contraseñas en Linux:

function spw() {
    cat /dev/urandom | tr -dc a-zA-Z0-9 | head -c ${1:-20}
}

Por ejemplo, spw 25 me dará una contraseña de 25 caracteres de [0-9a-zA-Z] .

    
respondido por el Arminius 06.08.2017 - 02:33
fuente
2

Overview

  

Si bien hay muchos ejemplos de programas generadores de contraseñas "aleatorias"   disponible en Internet, generando aleatoriedad puede ser complicado y   muchos programas no generan caracteres aleatorios de una manera que garantice   fuerte seguridad.

Tipo y fuerza de la contraseña generada

  

Los generadores de contraseñas aleatorias normalmente emiten una serie de símbolos de   longitud especificada Estos pueden ser personajes individuales de algunos   conjunto de caracteres, sílabas diseñadas para formar contraseñas pronunciables, o   palabras de alguna lista de palabras para formar una frase de contraseña. El programa puede ser   personalizadas para garantizar que la contraseña resultante cumpla con las normas locales.   política de contraseñas, por ejemplo, produciendo siempre una mezcla de letras, números y   caracteres especiales. Cabe señalar que tales políticas típicamente   reducir la fuerza ligeramente por debajo de la fórmula que sigue, porque   los símbolos ya no se producen de forma independiente.

Teniendo esto en cuenta, avancemos a POR QUÉ solo viste a-f y no a-z .

Conjuntos de símbolos

El motivo por el que vio a-f en lugar de a-z , se debe principalmente a su conjunto de símbolos. Por ejemplo:

Hexadecimal Numerals: (0-9, A-F) (e.g. WEP Key)  

Como puede ver, se puede crear para un WEP Key usando Hexadecimal Numerals Symbol Set. Si desea algo como (a-z, A-Z, 0-9), le sugiero el Case Sensitive Alphanumeric Symbol Set, que es más complejo que un conjunto de símbolos hexadecimal.

Resources

Puede leer más sobre las contraseñas y los conjuntos de símbolos generados con el siguiente enlace:

¡Soy el siguiente enlace!

Esperemos que esto te ayude a resolver tu problema.

    
respondido por el TazerFace 06.08.2017 - 03:01
fuente
1

Además de que los programadores son perezosos (como se indica en la respuesta de Arminuis, generar una contraseña hexadecimal es un trivial de una sola línea, incluso si no tiene nada más que el shell y las herramientas estándar), posiblemente las codificaciones "mejores" que contienen más bits En cada personaje tenemos problemas de usabilidad.

El problema no es tanto que la conversión de los números sea difícil o que haya números impares de bits en cada carácter que no suman fácilmente una potencia de dos (aunque la base-32 funciona muy bien para, por ejemplo, 80- o números de 160 bits).

El código de conversión es media docena de líneas de código, y no precisamente de ciencia espacial (división, módulo y búsqueda de tablas). El hecho de que los bits no se sumen es un poco molesto, pero no es realmente un problema. Solo significa que los últimos 8 caracteres codifican un poco menos de 40 bits (o los últimos 4 codifican un poco menos de 24 bits para la base 64). Si bien eso significa que hay menos entropía en esos caracteres finales, aún así la contraseña como tal es perfectamente aleatoria, no hay otro problema más que ser "menos elegante de lo que deseas". El hecho de que tengas ese = al final tampoco es un problema, solo puedes dejarlo.

El mayor problema es la interacción humana. Base-32 y base-64 contienen suficientes símbolos para producir (al azar) palabras o fragmentos de palabras legibles para el hombre, algunas de ellas son más aceptables y otras generan una reacción menos favorable.
Con hexadecimal, dead , f001 o affe (mono en alemán) es prácticamente lo peor que puede obtener, pero en la base-32, las subcadenas fuck o wanker serían completamente posibles, también como virtualmente cada insulto que existe en cualquier idioma que usa el alfabeto romano. Ahí lo tienes, universal, internacionalizado insult-o-matic para tus usuarios.

Además, naive base-32 contiene los símbolos 0 y O así como 1 y I que el usuario puede confundir, especialmente al imprimir o escribir contraseñas y -dirigirlos o tener que comunicarse por teléfono.
En base-64 no solo tienes 1 y I sino también i y j así como / para aumentar tu alegría. Y, por supuesto, decirle a alguien una cadena de 20 caracteres en mayúsculas y minúsculas por teléfono es pura felicidad.

Existen, al menos para la base 32, varias soluciones alternativas como el alfabeto RFC4648 o la codificación de Crockford que intentan abordar los problemas anteriores (símbolos confusos e insultos) en diferentes extensiones.

Sin embargo, estos son "torpes" de una manera diferente. Para alguien que usa regularmente el sistema, pronto se hace evidente que algo no está bien, algunos símbolos (en particular, 0 y 1 ) parecen no aparecer nunca. ¿Algo debe estar roto?

Ahora, el hexadecimal es un poco más largo, algunos caracteres más para escribir, pero no tiene ninguno de los problemas anteriores, y es el más trivial de generar.

    
respondido por el Damon 06.08.2017 - 12:49
fuente

Lea otras preguntas en las etiquetas