Generación de tokens y números aleatorios

2

Tengo un servidor Swift, donde actualmente la autenticación se maneja a través de una combinación simple de correo electrónico y contraseña con hash. Quiero reemplazarlo con un token de acceso (+ caducidad) para poder eliminar el almacenamiento del correo electrónico / contraseña en el dispositivo del usuario final para mejorar la seguridad, facilitando la revocación del acceso desde puntos finales específicos.

Actualmente, la implementación es multiplataforma, por lo que puedo desarrollarlo localmente (xcode, macOS) pero ejecutarlo en mi caja de Ubuntu. Por lo tanto, necesito una forma multiplataforma de generar números aleatorios.

Después de algunas búsquedas, obviamente encontré /dev/urandom , así que mi pregunta es si esto es lo suficientemente seguro como para usarlo. O debería considerar usar algo como arc4random + chacha20 y, de ser así, ¿por qué y esta implementación es buena?

Estoy planeando usar 128 bits como una longitud, ya que he leído sobre 64 bits simplemente porque no estoy lo suficientemente seguro (aunque probablemente en mi escala lo sería).

para referencia, aquí está mi actual implementación de demostración:

func random_data(_ length: Int) -> Data? {
    let stream = open("/dev/urandom", O_RDONLY)
    var buffer: [UInt8] = [UInt8](repeating: 0, count: length)

    let result = read(stream, &buffer, length)
    if result < 0 {
        return nil
    }
    return Data(bytes: buffer)
}

Tengo una función strcmp segura en mi base de código para evitar ataques de temporización, pero en cualquier caso lo más probable es que la divida en 2 int64 para verificación. PD Todavía tengo que averiguar si quiero poner a cero la memoria del token generado aleatoriamente una vez que se haya completado su trabajo. Esta es una tarea tediosa en Swift.

    
pregunta Antwan van Houdt 19.06.2017 - 21:54
fuente

2 respuestas

1

/dev/urandom es la solución multiplataforma que estás buscando.

Como han dicho @dandavis y @DuncanXSimpson, /dev/urandom es perfectamente apropiado para esto, y se comportará de la misma manera en todos los sistemas operativos Linux y Unix. Si desea ser multiplataforma con Windows, necesitará una sentencia if para llamar a CAPI cuando esté en una Entorno Windows.

(Tenga en cuenta que las implementaciones internas de /dev/urandom difieren significativamente entre linux, BSD, OSX y Solaris, causando mucha guerra de llamas entre los criptógrafos, pero todas son no bloqueantes, todas son seguras y todas se comportarán de la misma manera desde su perspectiva.)

Nota sobre cómo rodar el tuyo

No. Como dijo @dandavis, tomar un cifrado de flujo como ChaCha y construir un RNG a partir de él es sorprendentemente difícil de lograr. Y es peligroso porque es el tipo de cosa que le parecerá a un novato que está funcionando cuando, de hecho, está plagado de defectos sutiles.

Como dice el viejo adagio:

  

Cualquiera puede construir un sistema que él mismo no puede romper, pero muy pocos pueden construir un sistema que nadie pueda romper.

/dev/random y /dev/urandom son RNG bien establecidos para uso criptográfico. ¡Siéntete libre de tomar ventaja de ellos!

Nota sobre /dev/random vs /dev/urandom

¡Bienvenido a la guerra de llamas de mayor duración en criptografía!

No faltan las publicaciones de blogs compatibles con Google sobre esto, pero agregaré que cualquier artículo que diga "Usar siempre /dev/random " o "Usar siempre /dev/urandom " es incorrecto, cada uno tiene su lugar (excepto en FreeBSD y Solaris, donde funcionan de manera totalmente diferente y random es un enlace simbólico a urandom , que existe solo para la compatibilidad multiplataforma).

La diferencia sutil entre ellos es que /dev/random bloqueará y retrasará su programa si no cree que tenga suficiente aleatoriedad de alta calidad para completar su solicitud, mientras que /dev/urandom devolverá algo independientemente de la calidad (el ' u 'significa' ilimitado '). Esto es importante en ciertos casos extremos, sobre todo en pequeños dispositivos incrustados sin mouse / teclado desde el cual extraer aleatoriedad.

Dicho esto, para servidores regulares que han estado funcionando durante más de una hora con mucho tráfico de red, o que se ejecutan en procesadores con RNG de hardware integrado (2013+ para Intel y 2015+ para AMD), entonces /dev/urandom está perfectamente bien.

    
respondido por el Mike Ounsworth 06.08.2017 - 03:29
fuente
0

Sí, /dev/urandom es seguro. No hay razón para usar /dev/random en su lugar : realmente no es más seguro.

    
respondido por el Duncan X Simpson 06.08.2017 - 02:33
fuente

Lea otras preguntas en las etiquetas