Search code examples
windowsbatch-fileinputgnupg

How to simulate keypress in script? [GPG expert key generation]


How do I make a Batch (or C/C++) script (running a gpg command hundreds of times) that is able to simulate the following keyboard input (and being intelligent enough to wait for input to be asked)?

8
SEQ
4096
0y
Jean Dupont

born 1970-01-01 in Paris, France
O
correct horse battery staple
correct horse battery staple


I would like to generate myself a PGP keypair (for private communication), but I wish for the key's short id to be easy to remember, like FFFFFFFE for example.

The short id of a PGP key is the last 8 characters of its fingerprint. For your information, the fingerprint of a PGP key is a checksum (historically, SHA-1).

My wishes for the generated PGP key are the following:

  • Its short id (see above) must be easy to remember.
  • I want my key to be “unusual” so I have to use --expert mode.
    • By default, a generated key can both encrypt (E) and sign other people’s keys (C, “cert”), but I want mine to only sign other people’s keys.

Okay. So, I guess my solution for getting a “custom” key id is to generate lots of them (beware, I believe global entropy gets very diminished if you do that), and choose the one that I like most (like when your phone provider allows you to choose your future phone number in a list).

What I tried

By reading that page in the doc, I thought I could use gpg --batch --expert --gen-key gpg-keygen-settings.txt, with the following settings file:

Key-Type: RSA
Key-Length: 4096
Key-Usage: cert
Name-Real: Jean Dupont
Name-Comment: born 1970-01-01 in Paris, France
Expire-Date: 0
Passphrase: correct horse battery staple
%commit
%echo Done.

BUT it will not let me create a key whose usage is only to sign other people’s keys (cert). Indeed, the documentation says (for Key-Usage) that “Allowed values are ‘encrypt’, ‘sign’, and ‘auth’”. cert is the default, but using a blank Key-Usage field doesn’t work either.

What I believe I must do

I think the only way for me to generate all those keys with the settings I want, there is no solution but simulating key generation as if a real person was interactively running GPG’ shell.

Here is an excerpt of what must be done:

C:\> gpg --gen-key --expert
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection?

[…]

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: […]
[…]

So, uh. Thank you very much. Weird request, I know. Chuckles


Solution

  • Well, I didn’t find the solution I was looking for (something I could make run in background, not buggy, etc.)—and I am still open, for my personal culture, to better solutions and answers.

    Anyway, here is the AutoHotkey script I came up with. Very dirty. I coded a bit, then gave up and used the AutoScriptWriter tool to record a macro, and adapted the code to suit my needs (haha). The most annoying thing was to learn how to interact with GPG-Agent (pinentry).

    Loop 100
    {
        Run, cmd.exe /k "gpg --expert --gen-key"
        WinWait, C:\Windows\SYSTEM32\cmd.exe - gpg  --expert --gen-key, 
        IfWinNotActive, C:\Windows\SYSTEM32\cmd.exe - gpg  --expert --gen-key, , WinActivate, C:\Windows\SYSTEM32\cmd.exe - gpg  --expert --gen-key, 
        WinWaitActive, C:\Windows\SYSTEM32\cmd.exe - gpg  --expert --gen-key, 
    
        Sleep 1500
    
        Send +8{Enter}
        Send S{Enter}C{Enter}Q{Enter}
        Send +4+0+9+6{Enter}
        Send +0{Enter}o{Enter}
        Send Jean Dupont{Enter}
        Send {Enter}
        Send born {Shift Down}1970{Shift Up}6{Shift Down}01{Shift Up}6{Shift Down}01{Shift Up} in Paris, France{Enter}O{Enter}
        ; The "6" keypress above is to make a - on French AZERTY keyboards.
    
        WinWait, pinentry, 
        IfWinNotActive, pinentry, , WinActivate, pinentry, 
        WinWaitActive, pinentry,
    
        Send, correct horse battery staple{ENTER}
        Sleep 1500
        Send, correct horse battery staple{ENTER}
        Sleep 10000
        ;Send exit{Enter}
    }
    

    This little script allowed me to get a bucketload of keys, one of which having a short id I like.