Pregunta

Fondo

Estoy diseñando un sistema que permite el desarrollo de esquemas de autenticación dinámica para un usuario de contenido web estática. La motivación es comprobar la validez de generar grandes cantidades de contenidos web complejo a generar, pero sensible, y luego servir estáticamente con autenticación (reversably incorporar información cifrada) basada en cookies en su lugar, forzada por el servidor web inately. El uso de un cifrado AEAD-modo primitivo.

El problema

necesito para generar IVEC de teclas y que son válidos por un período de tiempo, digamos una semana (el par corriente válida). y que IVECs últimos / teclas son válidas también para decir 2 semanas (históricamente válida) y todos los datos cifrados con los secretos históricamente válidos sólo será re-cifrados con la corriente válida IVEC / KEY.

Lo que necesito es un CSPRNG determinista que las semillas de un número aleatorio y una contraseña y que puede producir de forma indexada bloques de 64 bits o 128 bits de los números. Si utilizo una semana-desde- "Jan 1 1970" como uno de los elementos Índice de mi CSPRNG hipotética que debería ser capaz de construir un sistema que cambia de forma innata teclas automáticamente a medida que pasa el tiempo.

enfoque que teniendo en cuenta

Ahora no veo tal funcionalidad en cryptopp, o lo hago ahora sabe la terminología bastante bien, y como cryptopp es la más avanzada de las bibliotecas de cifrado por ahí, no tengo confianza voy a encontrar otro. Así pues, si no puedo encontrar una implementación por ahí, que debería rodar la mía. Se genera una estructura de cadena estática de los datos concatinated y luego se hash (que se muestra a continuación) hacer el truco?

RIPEMD160 (RandomPreGeneratedFixedNonce: frase de contraseña: UInt64SinceEpoch: 128BitBlockIndexNumber);

Nota: Los blocknumbers serán asignados y tienen una estructura regular, por lo que por ejemplo para una de 128 bits digerir, los primeros 64 bits de bloque 0 serán para el IVEC, y todos elemento 1 para el 128-bit llave.

Es este un enfoque de sonido (-. Es decir, criptográficamente seguro)?

- edición: Poste aceptar el comentario -

Después de reflexionar, he decidido fusionar lo que originalmente considerada la frase de contraseña y el nonce / sal en una clave de 16 bytes (cryptographicall fuerte), y el uso de las técnicas descritas en el PKCS # 5 a basada en el tiempo de múltiples Derivar llaves. No hay una necesidad de una sal, ya que no se utilizan las frases de contraseña.

¿Fue útil?

Solución

Es una pregunta interesante.

En primer lugar, los vectores iniciales no tiene por qué ser cantidades aleatorias criptográficamente fuertes, pero debe ser único por mensaje. El IV es en realidad un tipo de valor de la sal que se asegura que los mensajes cifrados similares utilizando la misma clave no lo hacen mirada similar una vez que están cifrados. Se puede utilizar cualquier generador pseudoaleatorio rápida para generar el IV, y luego enviarlo (preferiblemente cifrada) junto con los datos cifrados.

Las claves, por supuesto, debe ser tan fuerte como el que prácticamente se puede hacer de ellos.

Su propuesta de hash de una cadena de texto que contiene un nonce, contraseña y datos de validez me parece ser muy razonable - es ampliamente en línea con lo que se hace por otro sistema que utilice una contraseña para generar una clave. Usted debe desmenuzar más muchas veces - no sólo una vez - para hacer la generación de claves computacionalmente caro (que será un problema mayor para cualquiera que trate de fuerza bruta la clave de lo que será para usted)

.

También puede ser que desee echar un vistazo al esquema de generación de claves establecido en PKCS # 5 (por ejemplo, http://www.faqs.org/rfcs/rfc2898.html ) que se implementa en cryptopp como PasswordBasedKeyDerivationFunction. Este mecanismo ya es ampliamente utilizado y conocido por ser seguro razonable (nota que PKCS # 5 recomienda hash de los datos de frase de contraseña al menos 1000 veces). Se podía añadir su período de validez y los datos del índice de la frase de acceso y el uso PasswordBasedKeyDerivationFunction tal como está.

Usted no dice qué algoritmo de cifrado que proponen usar para cifrar los datos, pero yo sugeriría que usted debe elegir algo ampliamente utilizado y conocido por ser seguro ... y en particular que te sugiero que utilice AES. También me gustaría sugerir el uso de una de las funciones de digerir SHA (tal vez como una entrada a PasswordBasedKeyDerivationFunction). SHA-2 es actual, pero SHA-1 es suficiente para los propósitos de generación de claves.

También no dicen lo que la longitud de clave que usted está buscando para generar, pero se debe tener en cuenta que la cantidad de entropía en las llaves depende de la longitud de la frase de contraseña que se utiliza, ya menos que la contraseña es muy de largo que será mucho menor que el keylength requiere idealmente.

El eslabón más débil de este esquema es la frase de contraseña en sí, y que siempre va a limitar el nivel de seguridad se puede achive. Siempre y cuando se pone sal sus datos (como lo están haciendo) y convertir la tecla generación caro para frenar los ataques de fuerza bruta que debe estar bien.

Otros consejos

  

Lo que necesito es un CSPRNG determinista que las semillas de un número aleatorio y una contraseña y que puede producir de forma indexada bloques de 64 bits o 128 bits de los números. Si utilizo una semana-desde- "Jan 1 1970" como uno de los elementos Índice de mi CSPRNG hipotética que debería ser capaz de construir un sistema que cambia de forma innata teclas automáticamente a medida que pasa el tiempo.

Bueno, pensar parte de la solución es utilizar un generador basado en el no-tiempo. De esa manera, si ambas partes comienzan con la misma semilla, luego ambos producen el mismo flujo de azar. Puede capa de sus "semanas desde la Semana 1, 1970" lógica por encima de eso.

Para hacer eso, se usaría OFB_mode<T>::Encryption. Se puede utilizar como un generador porque OFB utiliza el modo AdditiveCipherTemplate<T>, que deriva de RandomNumberGenerator.

De hecho, Crpyto ++ utiliza el generador en test.cpp de manera que los resultados pueden ser reproducidos si algo falla. He aquí cómo se usaría OFB_mode<T>::Encryption. También se aplica a CTR_Mode<T>::Encryption:

SecByteBlock seed(32 + 16);
OS_GenerateRandomBlock(false, seed, seed.size());

for(unsigned int i = 0; i < 10; i++)
{
    OFB_Mode<AES>::Encryption prng;
    prng.SetKeyWithIV(seed, 32, seed + 32, 16);

    SecByteBlock t(16);
    prng.GenerateBlock(t, t.size());

    string s;
    HexEncoder hex(new StringSink(s));

    hex.Put(t, t.size());
    hex.MessageEnd();

    cout << "Random: " << s << endl;
}

La llamada a recuperaciones OS_GenerateRandomBlock bytes desde /dev/{u|s}random y luego lo usa como una semilla compartida simulado. Cada ejecución del programa será diferente. Dentro de cada ejecución del programa, se imprime similar al siguiente:

$ ./cryptopp-test.exe
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD

Hay otro generador disponible que hace lo mismo, pero no es parte de la biblioteca Crypto ++. Se llama AES_RNG, y su basado en AES-256. Es una cabecera única aplicación, y se puede encontrar en la Crypto ++ wiki bajo RandomNumberGenerator .

También vea el tema reproducibilidad para la clase RandomNumberGenerator en el wiki de Crypto ++.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top