GPG (также известный как GnuPG) создавался как свободная альтернатива несвободному PGP. GPG используется для шифрования информации и предоставляет различные алгоритмы (RSA, DSA, AES и др.) для решения этой задачи.
Используемые версии
git: 2.39.0
gpg: 2.3.8
История изменения статьи
19.12.2022: Актуализировал версии ПО. Актуализировал инструкцию, сделал ее более подробной. Добавил информацию про создание дополнительных ключей и про подписание тегов.
Зачем подписывать коммиты?
По умолчанию в Git обязателен только механизм аутентификации, а авторизация не обязательна. Поэтому можно подписаться любым именем, и указать любой email. Никакой верификации при этом не происходит.
Вспоминаем: Чем аутентификация отличается от авторизации?
Ключ SSH позволяет получить доступ к репозиторию. Чаще всего ключ используется, чтобы пушить в репозиторий. Это пример аутентификации. Ключ SSH открывает нам доступ к репозиторию, а дальше вы можете оставить коммит от имени любого автора.
Ключ GPG позволяет подписывать конкретный коммит или тег. Таким образом владелец ключа может доказать свое авторство. А настройки популярных GIT хостингов позволяет запретить публиковать коммиты без GPG подписи.
Таким образом любой человек может попробовать выдать свои коммиты за ваши, чтобы внедрить вредоносный код.
Чтобы проверить, что коммиты действительно получены из доверенного источника, в Git есть несколько способов подписать и проверить исходники, используя GPG.
Вот как это выглядит в GitHub
Настройка GPG
Если вы хотите подписать что-то, вам необходим настроенный GPG и персональный ключ.
Посмотреть список ключей можно следующей командой.
gpg --list-keys --keyid-format long
pub ed25519/EFA62C59ACC854C1 2022-12-18 [SC] [ годен до: 2023-12-18]
831AAB443088938B8C4B1A99EFA62C59ACC854C1
uid [ абсолютно ] Struchkov Mark (Key for git commit) <mark@struchkov.dev>
sub cv25519/5E8003E311E63A37 2022-12-18 [E] [ годен до: 2023-12-18]
Создание нового ключа GPG
Генерируем новый ключ командой:
gpg --full-generate-key
Первым делом нам предложат выбрать тип создаваемого ключа
Выберите тип ключа:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (только для подписи)
(14) Existing key from card
Самый современный способ установлен по умолчанию (9). Также можно выбрать вариант (10). В нашем случае между ними не будет разницы.
Далее выбираем элептическую кривую. Также оставляем по умолчанию (1):
Выберите эллиптическую кривую:
(1) Curve 25519 *default*
(4) NIST P-384
(6) Brainpool P-256
Теперь устанавливаем срок действия ключа. Я обычно устанавливаю 1 год.
Выберите срок действия ключа.
0 = не ограничен
<n> = срок действия ключа - n дней
<n>w = срок действия ключа - n недель
<n>m = срок действия ключа - n месяцев
<n>y = срок действия ключа - n лет
Срок действия ключа? (0) 1y
После чего надо указать информацию о себе: ФИО, почту. В примечании можно указать зачем создается этот GPG ключ, чтобы потом не путаться.
Ваше полное имя: Struchkov Mark
Адрес электронной почты: mark@struchkov.dev
Примечание: Key for git commit
Вы выбрали следующий идентификатор пользователя:
"Struchkov Mark (Key for git commit) <mark@struchkov.dev>"
Сменить (N)Имя, (C)Примечание, (E)Адрес; (O)Принять/(Q)Выход? O
Подтверждаем введеные данные. После чего необходимо придумать пароль для защиты GPG ключа.
Отлично, теперь у нас есть мастер ключ. Желтым я выделил его идентификатор, он нам еще пригодится.
pub ed25519/EFA62C59ACC854C1 2022-12-18 [SC] [ годен до: 2023-12-18]
831AAB443088938B8C4B1A99EFA62C59ACC854C1
uid [ абсолютно ] Struchkov Mark (Key for git commit) <mark@struchkov.dev>
sub cv25519/5E8003E311E63A37 2022-12-18 [E] [ годен до: 2023-12-18]
Создание дополнительного ключа к основному
Мы создали так называемый мастер ключ. И можем использовать сразу его, а можем создать дополнительный ключ, который будет привязан к основному.
Делается это следующим образом
Далее вы увидите консоль gpg>
. Вводим туда команду addkey
и выбираем тип ключа. Нам нужен ключ для подписи (10).
gpg> addkey
Выберите тип ключа:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(10) ECC (только для подписи)
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
(14) Existing key from card
Ваш выбор? 10
Далее снова выбор элиптической кривой. Оставляем значение по умолчанию:
Выберите эллиптическую кривую:
(1) Curve 25519 *default*
(2) Curve 448
(3) NIST P-256
(4) NIST P-384
(5) NIST P-521
(6) Brainpool P-256
(7) Brainpool P-384
(8) Brainpool P-512
(9) secp256k1
Ваш выбор?
Указываем срок действия для дополнительного ключа и подтверждаем данные.
После этого важно вызывать команду save, чтобы сохранить новый ключ.
gpg> save
$
Если вывести информацию о ключах, то можно увидеть новый доплнительный ключ.
pub ed25519/EFA62C59ACC854C1 2022-12-18 [SC] [ годен до: 2023-12-18]
831AAB443088938B8C4B1A99EFA62C59ACC854C1
uid [ абсолютно ] Struchkov Mark (Key for git commit) <mark@struchkov.dev>
sub cv25519/5E8003E311E63A37 2022-12-18 [E] [ годен до: 2023-12-18]
sub ed25519/D3018BE7BA428CA6 2022-12-18 [S] [ годен до: 2023-12-18]
Добавление ключа в Git
Установив параметр user.signingkey
мы сообщаем гиту, что нужно использовать этот ключ по умолчанию для всех подписей.
$ git config --global user.signingkey D3018BE7BA428CA6
Индивидуально для репозитория можно указать другой GPG ключ.
$ git config --local user.signingkey 7BGC7M6M
Ручное добавление
Так же можно добавить ключ вручную в файл ~/.gitconfig
в параметр signingkey
.
Для глобальной настройки:
[user]
name = uPagge
email = spam@upagge.ru
signingkey = D3018BE7BA428CA6
[commit]
gpgsign = true
[core]
autocrlf = input
Для индивидуальной настройки репозитория используется переменная signingkey
в файле config
, который лежит в папке .git
.
[user]
name = Стручков Марк
email = mstruchkov@work.com
signingkey = 7BGC7M6M
Добавление ключа в GitHub
На примере GitHub рассмотрим, как добавить GPG ключ на git хостинг. Это позволит получить галочку верифицированного коммита у хостинга. Суть добавления одна и та же, не важно GitHub это или GitLab, или Gitea.
Чтобы добавить ваш ключ в GitHub перейдите в Settings > SSH and GPG keys. Вас интересует кнопка “New GPG key”
Теперь необходимо получить публичный ключ из приватного. Для этого выполните команду:
gpg --armor --export your_privat_key_id
Скопируйте целиком полученное значение, вставьте его в поле и нажмите “Add GPG key”. Если все прошло успешно, то вы увидите ваш ключ в списке.
Публикация открытого ключа
Это не обязательно, но в некоторых случаях необходимо сделать ваш ключ доступным и узнаваемым в Интернете.
Выполните эту команду:
gpg --send-keys 3AA5C34371567BD2
Однако, эта команда по какой-то причине работает не всегда. Тогда можно загрузить ключ вручную на один из сайтов, например на http://keyserver.ubuntu.com.
Для этого получаем публичный ключ командой:
gpg --armor --export your_privat_key_id
Подписание коммитов
Если вы хотите подписывать коммиты, а не только теги, вам нужно добавить -S
к команде commit
.
$ git commit -a -S -m 'Signed commit'
You need a passphrase to unlock the secret key for
user: "Scott Chacon (Git signing key) "
2048-bit RSA key, ID 0A46826A, created 2014-06-04
[master 5c3386c] Signed commit
4 files changed, 4 insertions(+), 24 deletions(-)
rewrite Rakefile (100%)
create mode 100644 lib/git.rb
Однако это может быть не удобно, если вы хотите подписывать каждый коммит. Тогда вам стоит установить глобальный параметр для git:
git config --global commit.gpgsign true
Чтобы увидеть и проверить эти подписи, существует также опция --show-signature
для команды git log
.
git log --show-signature -1
commit 5c3386cf54bba0a33a32da706aa52bc0155503c2
gpg: Signature made Wed Jun 4 19:49:17 2014 PDT using RSA key ID 0A46826A
gpg: Good signature from "Scott Chacon (Git signing key) "
Author: Scott Chacon
Date: Wed Jun 4 19:49:17 2014 -0700
Signed commit
Подписание тегов
Дополнительно можно подписывать теги к коммитам. Делается это также добавлением флага -s
:
git tag -s test
Дополнительно можно указать комментарий, который будет доступен для чтения при проверке подписи командой
git tag -v test
Резюмирую
Подписывать теги и коммиты - это отличное решение. При использовании подписей в своем обычном рабочем процессе убедитесь, что все в вашей команде понимают, как это сделать. Если вы этого не сделаете, то в конечном итоге потратите много времени, помогая людям понять, как переписать свои коммиты с помощью подписанных версий.
Убедитесь, что вы понимаете GPG и преимущества подписания, прежде чем принимать это как часть стандартного рабочего процесса.