¿Cómo obtener un 'millón de rondas de PKCS # 8 + PBKDF2' con OpenSSL?

11

Publiqué esta pregunta ¿Una clave privada SSH protegida con frase de contraseña es susceptible de un ataque de diccionario? hace unos días.

Un extracto de la final respuesta:

  

Con PKCS # 8 + PBKDF2 y un millón de rondas (OpenSSL necesitaría algunas   persuadiéndolo para producir eso), ganas 20 bits (porque 220 es   aproximadamente igual a un millón).

     

...

     

La herramienta de línea de comandos openssl no permite elegir el número de   iteraciones - pero OpenSSL, la biblioteca, lo admite (y lo hace también   OpenSSH, ya que OpenSSH utiliza OpenSSL). Produciendo el archivo de clave encriptada   requeriría algo de programación (llamar a la biblioteca con el   parámetros apropiados).

Ahora, ¿alguien sabe de alguna utilidad preexistente que pueda lograr lo anterior? De lo contrario, ¿alguien puede escribir un programa así y ponerlo a disposición del público para el bien de todos ... ya que estoy seguro de que a otros les resultará útil?

(Soy completamente nuevo en seguridad, criptografía, formatos clave y temas relacionados, y no estoy nada familiarizado con el código fuente de OpenSSL, por lo que no podré hacer que OpenSSL haga lo que es no estoy ya haciendo.)

    
pregunta Harry 01.08.2013 - 11:22
fuente

1 respuesta

15

El método más simple todavía es parchear OpenSSL, a saber, la herramienta de línea de comandos (no la biblioteca). Recorrido (asumiendo un host de Linux):

Descargue el código fuente de OpenSSL . Tome lo último, que la página muestra en rojo (en este momento, versión 1.0.1g ).

Desempaquete en algún directorio:

cd /tmp
tar xvzf ~/Downloads/openssl-1.0.1g.tar.gz

Edite el archivo fuente /tmp/openssl-1.0.1g/apps/pkcs8.c : busque la cadena "iter" hasta que desee encontrar estas líneas:

            else if (!strcmp (*args, "-noiter"))
                    iter = 1;
            else if (!strcmp (*args, "-nocrypt"))
                    nocrypt = 1;

Esa es la línea 158 en la versión 1.0.1g. Edita estas líneas para que se vean así:

            else if (!strcmp (*args, "-noiter"))
                    iter = 1;
            else if (!strcmp (*args, "-iter"))
                    {
                    if (!args[1]) goto bad;
                    iter = atoi(*(++args));
                    if (iter <= 0) goto bad;
                    }
            else if (!strcmp (*args, "-nocrypt"))
                    nocrypt = 1;

En otras palabras, solo agregue las 6 líneas que manejan un nuevo argumento de línea de comando llamado "-iter". Guarda el archivo.

Luego compila el código:

cd /tmp/openssl-1.0.1g
./config --prefix=$HOME/local
make
make test
make install

Y voilà! Tiene una nueva herramienta de línea de comandos openssl y una biblioteca en el subdirectorio local de su directorio de inicio (puede ponerlo donde desee con el --prefix opción, pero escribir en su directorio de inicio no necesita acceso root y no interferirá con las herramientas provistas por su sistema operativo). El comando de la herramienta de línea de comandos pkcs8 ahora tiene una opción -iter que se puede usar para seleccionar el número de iteraciones:

$HOME/local/bin/openssl genrsa -out rsaraw.pem 2048
$HOME/local/bin/openssl pkcs8 -topk8 -v2 aes128 -iter 1000000 -in rsaraw.pem -out rsapk8.pem

El archivo resultante se puede usar con un OpenSSL u OpenSSH completamente estándar, porque la biblioteca siempre ha admitido PBKDF2 con un millón de iteraciones. Aquí solo estamos parcheando la herramienta de línea de comandos para poder establecer ese recuento de iteraciones. Un vistazo al objeto resultante mostrará que el recuento de iteraciones se tuvo en cuenta:

openssl asn1parse -i -in rsapk8.pem

mostrará algo que comienza con:

  0:d=0  hl=4 l=1312 cons: SEQUENCE          
  4:d=1  hl=2 l=  74 cons:  SEQUENCE          
  6:d=2  hl=2 l=   9 prim:   OBJECT            :PBES2
 17:d=2  hl=2 l=  61 cons:   SEQUENCE          
 19:d=3  hl=2 l=  28 cons:    SEQUENCE          
 21:d=4  hl=2 l=   9 prim:     OBJECT            :PBKDF2
 32:d=4  hl=2 l=  15 cons:     SEQUENCE          
 34:d=5  hl=2 l=   8 prim:      OCTET STRING      [HEX DUMP]:A4E21F4F210DEB6F
 44:d=5  hl=2 l=   3 prim:      INTEGER           :0F4240
 49:d=3  hl=2 l=  29 cons:    SEQUENCE          
 51:d=4  hl=2 l=   9 prim:     OBJECT            :aes-128-cbc
 62:d=4  hl=2 l=  16 prim:     OCTET STRING      [HEX DUMP]:DAA184B3F6CC303B6A40A131E5C8C451
 80:d=1  hl=4 l=1232 prim:  OCTET STRING      [HEX DUMP]:2C15CF37D5ACC537AA92B
 (...)

¿Ver el " 0F4240 "? Eso es un millón, en hexadecimal.

El parche es trivial; Intentaré enviarlo a los mantenedores de OpenSSL.

    
respondido por el Tom Leek 01.08.2013 - 13:45
fuente

Lea otras preguntas en las etiquetas