Използвам YubiKey като ключ за двуфакторна автентикация и за подписване на Git комитите си. До преди няколко дни използвах YubiKey 4. Тъй като текущият ми компютър няма никакви USB-A портове, последната година мъкнех из раницата си USB-A към USB-C адаптери и използването на ключа беше пълна мъка. Затова реших, че е време да мина на „новия“ си YubiKey 5C и да не жонглирам повече с тези адаптери.
Всъщност ключът си стои у мен от доста време – поръчах го заедно със заместващ YubiKey 4, който получих заради проблема с Infineon TPM, който са открили, но чак сега реших, че е време да премина на новия ключ.
Другата причина да го направя точно сега е, че старите ми GPG ключове изтекоха и трябваше да ги издам наново, така че мога да използвам ключа за подписване на Git комитите си.
GPG лудницата
Ако си се занимавал с GPG ключове в миналото (или се занимаваш в момента), знаеш, че може да е доста трудно да го накараш да работи както трябва и безопасно, ако никога не си го правил. Пазене на главните ключове офлайн, местене на публични ключове, преиздаване на ключове след изтичането им, евентуално подписването им с предишни ключове за верификация, отнемане на ключове… Не е лесно да следваш най-добрите практики дори на теория. Когато стане дума за практиката, нещата стават изключително сложни.
Повечето уроци в мрежата препоръчват да използваш командния ред за генериране на ключовете, да навигираш из менюта с необичаен дизайн и общо взето е болка да ги накараш да заработят. Повечето казват да използваш офлайн машина, например Raspberry PI, и/или да генерираш главните ключове и подключовете офлайн и да държиш главния ключ далеч от компютъра си.
🤯
Занимавам се с това всеки януари вече почти 4 години. Страхувам се от момента, в който получа следната грешка, която ми показва, че подписващите ми ключове са изтекли.
error: gpg failed to sign the data
fatal: failed to write commit objectТази година реших, че е време да направя процеса много по-лесен и да използвам вграденото генериране на сертификати, за да избегна цялата тази каша с генерирането на GPG ключове и подобни.
Генериране на ключове директно върху YubiKey
Пак ще трябва да ползваме интерфейса в командния ред, но е малко по-ясен, защото има по-малко стъпки.
Първо трябва да настроим картата/устройството.
Настройка на картата/устройството
Изпълни gpg --card-status в терминала и трябва да видиш нещо такова:
Reader ………..: Yubico Yubikey 4 OTP U2F CCID
Application ID …: <Serial number>
Version ……….: 2.1
Manufacturer …..: Yubico
Serial number ….: <Device serial number>
Name of cardholder: unspecified
Language prefs …: en
Sex …………..: unspecified
URL of public key : \[not set\]
Login data …….: <e-mail or nothing>
Signature PIN ….: not forced
Key attributes …: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 9Ако виждаш нещо подобно и няма грешки, можеш спокойно да продължиш.
Изпълни gpg --card-edit
Ще се озовеш в интерфейс в командния ред, който показва същата информация в началото, а най-отдолу има команден промпт gpg/card>.
Напиши admin и натисни Enter.
Сега можеш да напишеш help, за да разбереш как да промениш информацията за собственика и PIN кодовете на картата.
Нещо, което ЗАДЪЛЖИТЕЛНО трябва да направиш, е да смениш PIN кодовете по подразбиране на картата. Те са два. Първият е PIN кодът, с който достъпваш ключовете на картата. Вторият е „Admin“ PIN или PUK (Personal Unblocking Code).
За целта напиши passwd и ще видиш меню:
gpg/card> passwd
gpg: OpenPGP card no. <Serial number> detected
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quitНапиши 1 и следвай указанията, за да смениш PIN кода. PIN кодът по подразбиране е 123456.
След като приключиш с това, избери 3, за да смениш Admin PIN. По подразбиране е 12345678.
След като смениш и двата кода, върни се в главното меню, за да довършиш обновяването на информацията за ключа.
Командите, които можеш да използваш, са:
name– за смяна на името на собственика на картатаlogin– за смяна на имейл адреса или логина на собственика на картата
След това можем да преминем към същинското генериране на ключове.
Генериране на ключове
Сега е време наистина да генерираме ключовете.
За целта напиши generate.
Ще бъдеш попитан Make off-card backup of encryption key? (Y/n), но както се споменава в документацията на YubiKey, това е само бекъп „на парче“ и няма да създаде пълен бекъп на тайните ключове, така че няма значение дали ще отговориш Yes, или No. Аз отговарям с No(n).
Ако на картата вече има запазени ключове, ще бъдеш попитан дали искаш да ги замениш:
gpg: Note: keys are already stored on the card!
Replace existing keys? (y/N)Увери се, че няма да заменяш нещо важно, от което нямаш бекъп, и продължи с Y. Ако има нещо важно, по-добре прекъсни целия процес с Ctrl+C.
Ще бъдеш попитан за PIN кода на картата, който зададе по-рано.
После трябва да избереш за колко време ще са валидни ключовете:
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)Ако искаш ключовете да са валидни само 1 година, напиши 1y.
Ще бъдеш помолен да потвърдиш датата на изтичане. Провери дали всичко е правилно и потвърди.
След това ще трябва да въведеш информация за собственика на ключа:
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: <Your name>
Email address: <Your e-mail>
Comment: <Comment is optional>
You selected this USER-ID:
"<Your name> <comment> <your e-mail>
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
Type `O` to confirm if everything seems correct.След това ще бъдеш попитан за Admin PIN или PUK. Това е необходимо, защото ще се извърши запис върху картата.
После, ако всичко е наред, YubiKey ще започне да мига и ще продължи да го прави известно време (при мен отнема към пет минути).
Когато приключи, ще видиш следното съобщение:
gpg: key <Short ID> marked as ultimately trusted
gpg: revocation certificate stored as '/Users/bisko/.gnupg/openpgp-revocs.d/<LONG ID>.rev' public and secret key created and signed.Запиши си <Short ID>, защото ще ни трябва по-късно.
В този момент можеш да излезеш от GPG промпта с quit или Ctrl+C.
Сега е време да запазим публичния ключ, за да можем да го използваме на друг компютър.
За целта изпълни следната команда:
gpg --armor --export <Short ID> > <Short ID>.ascТова ще експортира публичния ключ във файл с име <Short ID>.asc. Той ще ти трябва в бъдеще, ако искаш да използваш YubiKey на друг компютър или ако изгубиш GPG конфигурацията си.
За да възстановиш публичния ключ във връзката си с ключове (keyring), направи следното:
gpg --import < <Short ID>.asc
gpg: key <Short ID>: public key "Your Name <your@email>" imported
gpg: Total number processed: 1
gpg: imported: 1Много важна забележка. Ако това е нова инсталация на GPG или друг компютър, GPG няма сам да разпознае ключовете на картата. Трябва да изпълниш gpg --card-status, за да може да прочете картата и да засече ключовете върху нея.
Настройка на Git за подписване
За да настроиш Git да подписва комитите ти, трябва да добавиш следното в ~/.gitconfig.
В секцията [user] трябва да добавиш (или обновиш) следния ред:
signingkey = 0x<Short ID>
После, ако искаш да подписваш всичките си комити, добави следното в края на файла:
[gpg]
program = /usr/local/bin/gpg
[commit]
gpgsign = trueТака Git ще подписва всички твои комити.
За да настроиш GitHub, трябва да добавиш публичния си ключ към профила си. За целта отиди на GitHub -> Settings -> SSH and GPG keys -> New GPG key.
Ще видиш текстово поле, в което трябва да поставиш цялото съдържание на файла <Short ID>.asc, който генерирахме по-горе.
Ако искаш да копираш съдържанието на файла (на macOS), можеш да направиш така:
cat <Short ID>.asc | pbcopy
Това ще копира съдържанието на целия файл в клипборда.
Постави го в текстовото поле в GitHub и натисни бутона Add GPG key.
След това можеш да пробваш да направиш комит и push към GitHub и трябва да видиш симпатичния етикет Verified.
Дебъгване
Понякога нещата не работят от раз. За да съберем повече информация, можем да опитаме следното:
Подписване с GPG
Първо опитай да подпишеш нещо с ключа:
gpg -s <file>
Ако това не успее, опитай да разбереш защо, аз не съм експерт, за да помогна с това.
Погледни изхода на GitGIT_TRACE=1 git commit -am “test”
Това ще ти покаже точно какво прави Git, докато се опитва да направи комита и да го подпише. Ще ти даде насока защо подписването може да се проваля.
От него можеш да видиш и че Git изпълнява следната команда:
/usr/local/bin/gpg --status-fd=2 -bsau <Key ID>Можеш да опиташ да я изпълниш ръчно, за да видиш дали ще ти даде по-добра грешка.