métodos seguros para generar claves de sesión

2

Así que tengo esta aplicación web donde se supone que debo generar mi propia clave de sesión para usarla en el administrador de sesiones. Solo tengo algunas preguntas sobre enfoques seguros para esto.

  • Creo que para hacer esto seguro debería ser una clave generada al azar y es única en cada instancia de los procesos de mi aplicación web. ¿Mi suposición es correcta?

  • Estoy usando Go 1.2 para mi aplicación web y la forma en que estoy generando esta cadena aleatoria es mediante la siguiente función:

    func generateRandomSessionKey() string {
      rand.Seed(time.Now().UnixNano())
      alpha := "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789~!@#$%^&{}[]:,.*()_+-/?><."
      buf := make([]byte, KEYLENGTH)
    
        for i := 0; i < KEYLENGTH; i++ {
            buf[i] = alpha[rand.Intn(len(alpha))]
        }
    
     return string(buf)
    }
    

Esta función produce cadenas como: Hu@$pMaNZd.2)%Lpeet{6hYmKAxn:yYt

Ahora sé que algunos podrían discutir por qué no usar "crypto / rand" en lugar de "math / rand" , que ha demostrado ser más seguro, lo he intentado eso y al parecer el crypto/rand generó cadenas no válidas, por ejemplo \x16 que no puede ser utilizado por el marco web que estoy usando ( Beego ). Entonces, ¿lo que estoy haciendo aquí es un enfoque sensato y seguro para generar esta clave?

    
pregunta ymg 03.03.2014 - 01:59
fuente

2 respuestas

3

crypto / rand genera cadenas binarias. Por supuesto, las cadenas binarias no se pueden usar directamente como texto plano. Primero debe codificarlos en una representación de texto adecuada (por ejemplo, base64). Similar a su código provisto, puede usar crypto / rand de la siguiente manera:

import ("crypto/rand")

func rndString(n int) string {
    const alpha = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789~!@#$%^&{}[]:,.*()_+-/?><."
    var bytes = make([]byte, n)
    rand.Read(bytes)
    for i := 0; i < n; i++ {
        bytes[i] = alpha[bytes[i] % byte(len(alpha))]
    }
    return string(bytes)
}

Nunca debes inicializar el generador de números aleatorios con el tiempo de Unix. Para cualquier momento un atacante podría generar sesiones válidas muy fácilmente. Si está en un sistema Linux y si realmente desea agregar un PRNG, debe leer el valor de inicio de / dev / urandom, que puede tratarse como un archivo normal en sistemas Linux.

    
respondido por el DanielE 03.03.2014 - 09:22
fuente
2
  

Lo he intentado y, aparentemente, crypto / rand generó cadenas no válidas, por ejemplo. \ x16 que no puede ser usado por el framework web que estoy usando.

Lo que debe hacer es tomar los datos generados por crypto / rand y volver a codificarlos de manera que coincidan con lo que requiere su marco web. Debe mencionar en qué consiste el marco para hacer la pregunta y debe tratar de hacer coincidir su salida con la entrada exacta.

  

rand.Seed (time.Now (). UnixNano ())

Esa es una mala idea. Puedo adivinarlo fácilmente según la hora que sea y duplicar los resultados en mi final.

    
respondido por el Jeff Ferland 03.03.2014 - 04:08
fuente

Lea otras preguntas en las etiquetas