¿Cómo detectar si una clave privada de GnuPG tiene una frase de contraseña desde un script?

2

He escrito un script para ayudar a nuestros desarrolladores a almacenar una copia de sus claves privadas sin una contraseña en nuestro árbol Puppet (no comprometido con Git) para que nuestras cajas de Vagrant puedan usar Hiera con eyaml + gpg ( enlace ) para acceder a datos secretos durante las pruebas.

El script funciona muy bien, pero también me gustaría automatizar el proceso de verificación de que la clave secreta ha sido eliminada de una frase de contraseña correctamente en la copia.

Hasta ahora, la única forma que encontré es manual: ejecutar gpg --homedir ... --edit-key keyid y luego en el indicador interactivo ejecute password y busque un mensaje This key is not protected. .

Me gustaría hacer eso automáticamente en el script. Básicamente, quiero saber cómo la herramienta gpg sabe que debería imprimir este mensaje. De la respuesta en enlace y leer el código fuente de GnuPG en g10 / export.c Yo concluya que "sin frase de contraseña" en realidad se considera como "frase de contraseña es una cadena vacía" y el código realmente intenta descifrar una cadena aleatoria con la frase de contraseña y verificar que el resultado contenga un patrón aleatorio repetido.

¿Esto es correcto?

Si es así, ¿hay alguna manera de evitar tener que volver a implementar todo el proceso por mi cuenta pero en su lugar usar la herramienta de línea de comandos gpg o algunas API de Python / Ruby para hacer eso por mí? Miré algunos frontales de Python y Ruby para gpgme pero no vi algo como esto allí.

Veo en g10 / build-packet.c que debería esperar alguna salida diferente si el paquete está protegido o no, pero al intentar comparar volcados de claves secretas protegidas contra no protegidas no se hizo ' No cede nada excepto pequeñas diferencias en hashes. Podría estar malinterpretando el código allí.

    
pregunta Amos Shapira 09.10.2015 - 04:17
fuente

1 respuesta

2

A partir de mis pruebas, gpg --list-packets producirá resultados diferentes dependiendo de si la clave está encriptada o no. Una clave generada sin frase de contraseña tendrá directamente información sobre la clave revelada:

:secret key packet:
    version 4, algo 1, created 1444376378, expires 0
    skey[0]: [1024 bits]
    skey[1]: [17 bits]
    skey[2]: [1017 bits]
    skey[3]: [512 bits]
    skey[4]: [512 bits]
    skey[5]: [510 bits]
    checksum: 9df4
    keyid: [snip]

mientras que una clave con frase de contraseña solo proporciona información sobre las partes de clave pública y los procedimientos de cadena a clave en uso:

:secret key packet:
        version 4, algo 1, created 1378729401, expires 0
        skey[0]: [1024 bits]
        skey[1]: [17 bits]
        iter+salt S2K, algo: 3, SHA1 protection, hash: 10, salt: e182c39f07747f0c
        protect count: 65011712 (255)
        protect IV:  d5 0d 20 dc cb a2 e9 16
        encrypted stuff follows
        keyid: 99543578D453449B

Aún tendrías que analizar la salida, pero esto debería ser lo suficientemente estable como para ir directamente a la ausencia de una línea [whatever] S2K (hay diferentes procedimientos S2K, así que asegúrate de buscarlos todos o usar algún tipo de comodín tarjeta). Lamentablemente, no hay una salida especial de --with-colons para --list-packets que sería más fácil y más confiable de analizar.

    
respondido por el Jens Erat 09.10.2015 - 09:50
fuente

Lea otras preguntas en las etiquetas