Found an easy approach. You need pem2openpgp
utility from monkeysphere project and gpg2
's ability to import existing key as subkey.
First convert SSH key to OpenPGP format. You have to privode a new user ID as required by GPG.
$ pem2openpgp $TEMP_USERID < .ssh/id_rsa | gpg2 --import
Now you have a new user ID with your SSH key as master key. You can check it with gpg2 -K
(I set TEMP_USERID
to TEST
). Also write down keygrip of newly imported key:
$ gpg2 -K --with-keygrip $TEMP_USERID
sec rsa4096 2018-03-02 [C]
21C766CAC691F395D640E8207E9F9F883D1E49D8
Keygrip = AAB27E63622E87B27AC34293EDF52C3AB016CA2E
uid [ unknown] TEST
Now use gpg2 --expert --edit-key
on your master key and import above key as your subkey:
$ gpg2 --expert --edit-key $YOURUSERID
gpg> addkey
......
(13) Existing key
Enter the keygrip: AAB27E63622E87B27AC34293EDF52C3AB016CA2E
......
gpg2
will ask you lots of questions as usual. Remember to toggle correct key capabilities (sign: off, encrypt: off, auth: on).
After this you should have the imported SSH key as your master key's subkey. Check it:
$ gpg2 -K $YOURUSERID --with-keygrip
sec rsa4096 2016-02-02 [SC]
......
uid [ 绝对 ] CUI Hao (cvhc) <[email protected]>
......
ssb rsa4096 2018-02-21 [A]
Keygrip = AAB27E63622E87B27AC34293EDF52C3AB016CA2E
You can use gpg2 --export-ssh-key
to verify the imported subkey is indeed the same as original SSH key.
Note that the temporary user id used for key import is still in your keyring. You must delete it manually. GnuPG prevent you from removing public key / user id without deleting corresponding private keys. However, since the temporary user and your imported subkey share shares the same private key, gpg2 --delete-secret-keys $TEMP_USERID
also deletes imported subkey.
My solution is to backup private keys in ~/.gnupg/private-keys-v1.d
and move it back after gpg2
removed imported subkey.
I submit a feature request to ask GnuPG for an option to delete the public key without affecting private key: https://dev.gnupg.org/T3808