Expertus metuit
Разбираемся в GnuPG
2013-03-06 15:14
Теги: linux, security

Перед вами 1001-я статья о GnuPG, не читайте её.

Здесь написано о GnuPG, как им пользоваться и при этом понимать, что делаешь.

В статье идёт речь исключительно о консольном клиенте gpg, удобнее всего с ним работать в терминале на linux/macos-машине.

Официальный сайт GnuPG здесь, огрызки смыслов в виде официального руководства здесь, статья в ру-википедии здесь. А эта статья адресована техноманьякам, поскольку нормальные люди GnuPG (как и PGP) использовать не будут.

Всё и сразу

Короткая выжимка основных операций. Подробности в разделах ниже.

Шифруем файл GPL.txt публичным ключом (моим), результат записывается в GPL.txt.gpg:

$ gpg -e -r sergei@regolit.com GPL.txt

Расшифровываем присланный файл и записываем результат в файл GPL.txt:

$ gpg -d  GPL.txt.gpg > GPL.txt

Создаём цифровую подпись (т.е. подписываем) файл GPL.txt, подпись создаётся в отдельном файле GPL.txt.sig (т.н. detached signature), в аргументе -u john.smith@example.com указываем, какой ключ использовать:

$ gpg -u john.smith@example.com --detach-sign GPL.txt

Вместо --detach-sign можно писать -b:

$ gpg -u john.smith@example.com -b GPL.txt

Ещё можно сделать цифровую подпись вместе с самим документом, это делается такой командой:

$ gpg -u john -s GPL.txt

Полученный на прошлом шаге файл GPL.txt.gpg вместе с подписью содержит и сам документ, его можно извлечь такой командой:

$ gpg --output GPL.txt --decrypt GPL.txt.gpg

А чтобы просто проверить подпись документа, делаем так (это внешняя подпись, поэтому для корректной проверки рядом должен лежать файл GPL.txt):

$ gpg --verify GPL.txt.sig 

Если сам файл для проверки именуется по-другому, можно просто указать его имя в команде:

$ gpg --verify GPL.txt.sig lincense.txt

Ключи

Главный компонент GnuPG — ключ. Он состоит из двух частей: приватной и публичной. Приватная хранится только у владельца ключа в тщательно запароленном виде. Публичная распространяется свободно в интернетах.

Приватный ключ используется для:

  • подписывания данных;
  • дешифрования зашифрованных файлов.

Во всех операциях, где используется приватный ключ, обязательно нужен вводить пароль к приватному ключу (дальше этот пароль называется: парольная фраза).

Публичный ключ используется для:

  • проверки подписи данных;
  • шифрования данных.

Таким образом, если вы хотите кому-то отправить зашифрованный текст, который получатель сможет расшифровать, вы берёте публичный ключ этого пользователя, шифруете этим ключом данные, отправляете. Получатель берёт приватную компоненту ключа и расшифровывает.

А если вы хотите подтвердить подлинность текста, вы берёте свой приватный ключ, вычисляете при помощи него и первоначального текста специальный набор байтов, называемый подписью, и отправляете подпись вместе с документом. Получатель берёт ваш публичный ключ, текст и подпись, скармливает это всё специальному алгоритму, который говорит: «да, эта подпись соответствует этому публичному ключу для этого текста». Таким образом получатель может быть уверен, что он получил точно тот же документ, который вы ему отправили.

Пара приватный-публичный ключ создаётся такой командой:

$ gpg --gen-key

Детально её описывать не буду, сами разберётесь, в крайнем случае просто Enter жмите, параметры по умолчанию вполне сгодятся.

А теперь важный момент.

Дальше в тексте я буду явно разделять по смыслам слова ключ и криптоключ. Ключ — это такая собирательная сущность GnuPG, объединяющая несколько криптоключей, подписи, идентификаторы юзеров и т.п. А криптоключ — это бинарные данные, непосредственно использующиеся в криптоалгоритмах для операций типа подписывания или шифрования.

Идентификация ключей

При работе с gpg нужно указывать, какой именно ключ вы хотите использовать, поскольку в кейринге как правило хранится много ключей. Как минимум это ваш ключ (приватная и публичная часть), плюс публичные ключи других людей.

У каждого ключа есть набор параметров, по которым его можно идентифицировать. Прежде всего, это ID — идентификатор ключа, выглядит он обычно как строка из восьми hex-символов, например, 4600813F. Ещё в качестве идентификатора можно использовать ID юзера из этого ключа. Программа gpg достаточно умная и способна найти ключ, например, лишь по одному емейлу или полному имени, или даже части полного имени.

Поэтому, если у вас в кейринге есть публичный ключ, в юзерах которого есть емейл js@server.tld и вы хотите отправить ему зашифрованный текст, можно команду зашифровки файла набрать так:

$ gpg -o test.txt.encrypted -r js@server.tld -e test.txt

Здесь в параметре -r js@server.tld указывается емейл получателя. Вместо емейла можно указать ID конкретного ключа, или полное имя, или только имя, или фамилию — gpg почти всегда что-то да найдёт, что введённому тексту соответствует.

Если вы хотите подписать файл, это можно сделать так:

$ gpg -u john -s test.txt
You need a passphrase to unlock the secret key for
user: "John Smith (esquire) <john.smith@example.com>"
2048-bit RSA key, ID 4600813F, created 2013-03-11

Enter passphrase: 

Здесь имя передаётся в команде -u john.

Да, да, в одних командах для указания ключа используется команда -u, в других — -r, «Понять это нельзя, можно только запомнить».

Публичный ключ

Сразу начнём со списка:

$ gpg --list-keys 
--------------------------------------------------------
pub   2048R/4600813F 2013-03-11
uid                  John Smith (esquire) <john.smith@example.com>
sub   2048R/CA71F43D 2013-03-11

Если у вас свежий кейринг с одним ключом, то после выполнения команды вы получите у себя в терминале нечто подобное. На примере этого листинга объясню базовые вещи о структуре gnupg-ключа.

Команда --list-keys печатает список всех публичных ключей. Каждый публичный ключ состоит из нескольких независимых блоков данных, каждый блок1 в листинге печатается в отдельной строке (а между разными ключами в выводе --list-keys печатается пустая строка). В одном ключе скрывается сразу несколько криптоключей, которые используются в разных случаях (например, один криптоключ используется для подписывания, а для шифрования — другой). Помимо криптоключей, в блоках ключа хранятся и другие данные (о них будет написано ниже).

Начнём с первого блока:

 pub   2048R/4600813F 2013-03-11

В первой колонке указывается тип данных в этом блоке, строка pub означает, что в там находится публичная часть мастер-криптоключа, она используется для проверки подписи, сделанной приватной частью. Это очень важный момент, запомните его: для шифрования данных мастер-криптоключ не используется, только для подписи/проверки подписи.

Во второй колонке указываются параметры криптоключа, в нашем случае 2048R/4600813F означает, что в основе блока лежит криптоключ длиной 2048 бит, буква R после длины ключа означает, что это RSA-ключ (вместо R могут быть и другие символы, например, D для DSA-ключа). Строка 4600813F — это ID криптоключа (в идеале каждый новый ключ должен иметь свой собственный ID, но на практике всё не так радужно — уже есть примеры коллизий).

В третьей колонке указывается дата создания криптоключа, у нас это 2013-03-11.

В четвёртой колонке указывается дата окончания, в нашем примере она пустая, то есть криптоключ никогда не устаревает.

Деление на колонки весьма условное, но обычно из контекста понятно, где какие данные. Чтобы получить пригодный для автоматического парсинга вывод, добавьте аргумент --with-colons.

Теперь следующий блок:

uid                  John Smith (esquire) <john.smith@example.com>

Тип данных uid означает, что здесь лежит информация о юзере, по сути весь текст тут является ID этого юзера. Юзер служит для привязки бинарных данных ключа к конкретной персоне. В нашем блоке данных user-ID: John Smith (esquire) <john.smith@example.com>.

Следующий блок:

sub   2048R/CA71F43D 2013-03-11

Тип sub означает, что здесь находится публичная часть подчинённого криптоключа. Остальные параметры такие же, как в мастер-криптоключе: RSA-ключ 2048 бит, ID ключа CA71F43D, дата создания — 2013-03-11. Подчинённый криптоключ используется, для шифрования/дешифрования данных (публичная часть для шифрования, приватная — для дешифрования).

Приватный ключ

Список приватных ключей смотрим командой --list-secret-keys

$ gpg --list-secret-keys                            
--------------------------------------------------------
sec   2048R/4600813F 2013-03-11
uid                  John Smith (esquire) <john.smith@example.com>
ssb   2048R/CA71F43D 2013-03-11

Формат вывода здесь такой же, как и для публичных ключей. Обратите внимание, что ID криптоключей здесь те же самые, то есть криптоключи приватной и публичной частей образуют связную пару.

Здесь sec означает приватный мастер-криптоключ, он используется для создания подписи данных.

ssb обозначает блок данных с приватным подчинённым криптоключом. Этот ключ используется для расшифровывания данных, зашифрованных публичным парным криптоключом из предыдущей секции.

В приватном ключе дублируются все записи о юзерах.

Вы уже могли обратить внимание, что в качестве ID всего ключа используется ID мастер-криптоключа. Также вспомните, суть мастер-криптоключа — он используется для подписывания данных, но не для шифрования. Эти две вещи связаны напрямую, криптоключ для подписывания не просто так был выбран главным в GnuPG-ключе: все важные блоки данных в публичном ключе подписаны мастер-криптоключом. Это означает, что распространяемый публичный ключ невозможно модифицировать, не сломав подписи блоков. Например, если злоумышленник подменит какой-нибудь емейл (т.е. uid-блок) в публичном ключе, то он не сможет этот подменный блок подписать так, чтобы он прошёл проверку публичной частью мастер-криптоключа.

Распространение публичного ключа

Базовые моменты

Принцип функционирования GnuPG описан много где, поэтому без подробностей: храните зашифрованный уникальной парольной фразой приватный ключ в надёжном месте, раздавайте свой публичный ключ на все доступные сервера публичных ключей (и не забывайте после обновления ключа опять его загружать на сервер).

Некоторые сервера ключей являются на самом деле пулами, то есть при обращении к адресу сервера, обратно отдаётся ip-адрес случайного сервера из списка. Пример такого пула — hkp://pool.sks-keyservers.net. Клиент обращается к серверу либо за новым ключом (нужно знать его ID), либо за обновлением уже существующего.

Вот как можно запросить публичный ключ (в данном примере мой ключ):

$ gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 5B20C7D2

А вот так можно отправить свой публичный ключ на сервер (это я обновляю свой ключ, поэтому указываю его ID):

$ gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 5B20C7D2

Обновить локальные публичные ключи в кейринге можно командой --refresh-keys, она для каждого ID ключа попытается скачать более новую его версию и обновить записи в кейринге:

$ gpg --refresh-keys --keyserver hkp://pool.sks-keyservers.net

Практически все серверы ключей не позволяют удалять блоки данных из ключа. Объяснение этому простое — подписываются только отдельные блоки в ключе, поэтому если удалить блок вместе с его подписью, мы получим валидный (но изменённый злоумышленником) ключ. Поэтому, даже если вы удалите из публичного ключа, например, user-ID-блок, вы не сможете этот блок удалить с сервера ключей. Неким аналогом удаления блоков является так называемый отзыв, специальный вид цифровой подписи, помечающий блок как более невалидный. Программы обычно такие блоки либо игнорируют как несуществующие, либо выдают специальные предупреждения, если на невалидные блоки завязаны какие-либо действия.

Таким образом, очень внимательно подходите к вопросу выбора имени или добавления подчинённого криптоключа, после публикации публичного ключа «откатить» изменения полностью уже не получится.

Распространение изменений

Два стандартных способа распространения публичного ключа: через дамп с последующим выкладыванием куда-нибудь или через сервер ключей. Про экспорт на сервер я писал выше (команда --send-keys). А файловый дамп делается так:

$ gpg --armor -o 4600813F.pub --export 4600813F

Если не указывать --armor, то ключ будет выдан в бинарном формате. Дальше этот файл (4600813F.pub) можно, например, на сайте выложить вместе с такой инструкцией по импорту:

$ gpg --fetch-keys http://example.com/4600813F.pub

Эта команда сама скачает и затем импортирует ключ в кейринг.

При любом импорте существует несколько сценариев применения изменений, «тонкая настройка» этого делается через команду --import-options, впрочем, действия по умолчанию вполне нормальны и особой необходимости влезать в этот процесс нет.

Редактирование ключа

Базовые моменты

Редактирование ключа происходит в полуинтерактивном режиме, который запускается командой --edit-key:

$ gpg --edit-key 4600813F 
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  2048R/4600813F  created: 2013-03-11  expires: never       usage: SC  
                    trust: ultimate      validity: ultimate
sub  2048R/CA71F43D  created: 2013-03-11  expires: never       usage: E   
[ultimate] (1). John Smith (esquire) <john.smith@example.com>

gpg> 

Также можно вместо ID ключа использовать имя юзера, вот эквивалентная команда:

$ gpg --edit-key john.smith@example.com

Посмотреть список всех2 доступных команд можно командой help. В процессе выполнения команд данные в ключ сразу не записываются, получается такая типа транзакционность. Записать изменения (и сразу же выйти) можно командой save. Выйти без сохранения можно либо через Ctrl+C, либо командой quit с двумя подтверждениями.

Чаще всего при редактировании ключа по-настоящему меняется только публичная часть: редактируется блок данных (либо добавляется новый) и для него создаётся новая подпись.

Редактирование юзеров

Наиболее часто используется команда adduid, она добавляет в ключ новый блок с user-ID: привязать к ключу новый емейл, например; сама команда крайне простая: вводим данные юзера, вводим парольную фразу ключа и всё.

gpg> adduid
Real name: John Smith
Email address: js@server.tld
Comment:
You selected this USER-ID:
    "John Smith <js@server.tld>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

You need a passphrase to unlock the secret key for
user: "John Smith (esquire) <john.smith@example.com>"
2048-bit RSA key, ID 4600813F, created 2013-03-11


pub  2048R/4600813F  created: 2013-03-11  expires: never       usage: SC  
                    trust: ultimate      validity: ultimate
sub  2048R/CA71F43D  created: 2013-03-11  expires: never       usage: E   
[ultimate] (1). John Smith (esquire) <john.smith@example.com>
[ unknown] (2). John Smith <js@server.tld>

gpg>

Ввод парольной фразы нужен для создания подписи для добавленного юзера, подпись подтверждает, что юзер добавлен именно владельцем этого ключа.

Чтобы удалить user-ID, нужно в режиме редактирование снача авыделить его командой uid N, где N — номер user-ID из списка юзеров, на листинге выше номера указаны в круглых скобках перед непосредственно ID. После выделения командой deluid выделенных юзеров можно удалить. Да, выбрать можно сразу несколько юзеров, выбранные в списке отмечаются звёздочкой:

[ unknown] (1). John Smith <js@server.tld>
[ ultimate] (2)* John Smith (esquire) <john.smith@example.com>

Первичный (по-английски — primary) обозначается точкой после номера юзера, в листинге выше это (1). Сменить первичного юзера можно так: выделить его (через uid 2, например) и далее команду primary:

gpg> uid 2

pub  2048R/4600813F  created: 2013-03-11  expires: never       usage: SC  
                 trust: ultimate      validity: ultimate
sub  2048R/CA71F43D  created: 2013-03-11  expires: never       usage: E   
[ultimate] (1). John Smith <js@server.tld>
[ultimate] (2)* John Smith (esquire) <john.smith@example.com>

gpg> primary

You need a passphrase to unlock the secret key for
user: "John Smith <js@server.tld>"
2048-bit RSA key, ID 4600813F, created 2013-03-11


pub  2048R/4600813F  created: 2013-03-11  expires: never       usage: SC  
                 trust: ultimate      validity: ultimate
sub  2048R/CA71F43D  created: 2013-03-11  expires: never       usage: E   
[ultimate] (1)  John Smith <js@server.tld>
[ultimate] (2)* John Smith (esquire) <john.smith@example.com>

Первичный юзер используется как юзер по умолчанию при разруливании всяких сложностей (коллизий, например) или при отображении параметров найденного ключа (при вводе парольной фразы, например), если у вас в ключе несколько юзеров.

Командой deluid можно удалить выделенные блоки с user-ID, однако смысл в этой команде есть, только если вы ещё не успели поделиться обновлённым публичным ключом с другими.

Командой revuid можно отозвать выделенные user-ID, отозванные юзеры помечаются специальным образом и во многих случаях это почти то же самое, что удалённый. Необходимость в отзыве возникает, например, если вы потеряли один из емейлов и хотите пометить его в списке, чтобы его другие не использовали.

Редактирование подчинённых криптоключей

Блоки криптоключей можно удалять, добавлять и отзывать. Криптоключи бывают двух видов: для подписывания и для шифрования. Создаются они всегда парой: приватный уходит в приватный ключ, а публичный криптоключ — в публичный.

Посмотреть, какие у вас криптоключи можно, к сожалению, только из режима редактирования (команда --list-keys не показывает, какого типа криптоключ находится в блоке). Вот пример вывода команды list режима редактирования:

pub  2048R/4600813F  created: 2013-03-11  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048R/CA71F43D  created: 2013-03-11  expires: never       usage: E   
sub  2048D/DAD9C2B3  created: 2013-03-11  expires: never       usage: S   
[ ultimate] (1). John Smith (esquire) <john.smith@example.com>
[ unknown] (2)  John Smith <js@server.tld>

В списке видно два подчинённых криптоключа, ID первого CA71F43D, а второго — DAD9C2B3. В конце строки можно видеть, как этот криптоключ можно использовать: usage: S означает signing, то есть этим криптоключом можно подписывать сообщения, а usage: E означает encryption, то есть криптоключом можно шифровать данные. Запись usage: SC означает, что ключ можно использовать для подписывания (Signing), сертификации (Certification, потом расскажу, что это такое). Есть ещё также буква A, которая означает authentication, но на практике это почти не используется (чуть подробнее здесь можно прочитать).

Любой подчинённый криптоключ можно удалить или отозвать.

После создания новый криптоключ можно использовать для шифрования или подписывания вместо изначального. Так написано в официальной документации, однако как именно это делать, там упомянуто очень мутно. Хотя в действительности всё просто, пусть у нас вот такой набор криптоключей:

pub  2048R/4600813F  created: 2013-03-11  expires: never       usage: SC  
                 trust: ultimate      validity: ultimate
sub  2048R/CA71F43D  created: 2013-03-11  expires: never       usage: E   
sub  2048D/D306C7D0  created: 2013-03-11  expires: never       usage: S   
sub  2048R/261AB303  created: 2013-03-11  expires: never       usage: E   
[ultimate] (1). John Smith (esquire) <john.smith@example.com>
[ultimate] (2)  John Smith <js@server.tld>

Здесь у нас:

  • мастер-криптоключ с ID 4600813F — этим криптоключом можно создавать подписи (буква S);
  • RSA-криптоключ с ID CA71F43D — для шифрования (буква E), этот криптоключ был создан ;
  • DSA-криптоключ с ID 261AB303 — для подписи (буква S), этот криптоключ был создан командой addkey;
  • RSA-криптоключ с ID 261AB303 — опять для шифрования, этот ключ также был отдельно создан командой addkey.

Допустим, какой-то человек получил этот публичный ключ и хочет зашифровать им файл GPL.txt, для этого он использует вот такую команду:

$ gpg --recipient john.smith@example.com --encrypt GPL.txt

Каким именно криптоключом будет зашифрован файл? У нас в ключе их два: один с ID CA71F43D и второй с ID 261AB303. Какой из них использовался? Ответа на этот вопрос нет, хрен его знает, как GPG выбирает, каким именно подчинённым криптоключом шифровать данные, алгоритм выбора нигде в документации не описан (поправьте, если я не прав). В данной ситуации использовался криптоключ с ID 261AB303, видимо, при прочих равных GnuPG выбирает последний созданный ключ (плюс, возможно, с более дальней датой окончания).

Однако можно указать gpg, какой конкретно криптоключ использовать для шифрования (обратите внимание на восклицательный знак после ID подчинённого криптоключа):

$ gpg --recipient CA71F43D! --encrypt GPL.txt

Восклицательный знак после ID криптоключа заставляет gpg использовать именно этот криптоключ и запрещает обычную процедуру его поиска. Точно такой же метод можно использовать для подписывания данных. Посмотрите на разницу между вот этими двумя командами, отличающимися только лишь одним восклицательным знаком:

$ gpg -o GPL.signed -u 4600813F -s GPL.txt

You need a passphrase to unlock the secret key for
user: "John Smith (esquire) <john.smith@example.com>"
2048-bit DSA key, ID D306C7D0, created 2013-03-11 (main key ID 4600813F)

Enter passphrase:

сравните с:

$gpg -o GPL.signed -u 4600813F! -s GPL.txt

You need a passphrase to unlock the secret key for
user: "John Smith (esquire) <john.smith@example.com>"
2048-bit RSA key, ID 4600813F, created 2013-03-11

Enter passphrase:

В обоих случаях в качестве юзера передан ID мастер-криптоключа, однако в первом случае gpg вместо него использует подчинённый криптоключ (с ID D306C7D0). А вот если указать восклицательный знак, то будет использован в точности указанный криптоключ, в данном случае — мастер-криптоключ.

С подписыванием ровно то же самое: непонятно как выбирается ключ для подписи, явно ключ можно указать, добавляя восклицательный знак после ID криптоключа.

Подписывание чужого ключа

Одной из главных декларируемых фич PGP является сеть доверия (web of trust), что это такое, можете почитать в википедии (только на английском). В основе сети доверия лежит подписывание ключей, суть его в следующем: если вы доверяете человеку, у вас есть его публичный ключ и вы абсолютно точно уверены, что это именно его публичный ключ, то вы можете подписать его публичный своим приватным ключом. Такой процедурой вы подтверждаете, что этот ключ действительно принадлежит его владельцу. Чем больше таких авторитетных подписей, тем достовернее и надёжнее ключ (что бы это ни значило, но таков ритуал).

Для просмотра подписей блоков данных ключа есть команда --list-sigs, она работает как команда --list-keys, только для каждого блока показывает его сигнатуру:

$ gpg --list-sigs 
--------------------------------------------------------
pub   2048R/4600813F 2013-03-11
uid                  John Smith (esquire) <john.smith@example.com>
sig 3        4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>
uid                  John Smith <js@server.tld>
sig 3        4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>
sub   2048R/CA71F43D 2013-03-11
sig          4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>
sub   2048D/D306C7D0 2013-03-11
sig          4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>
sub   2048R/261AB303 2013-03-11
sig          4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>

Структура листинги аналогична команде --list-keys, только теперь мы видим дополнительные строки — они начинаются со слова sig — это подписи (иногда ещё говорят сигнатуры) для соответствующих блоков. Подписи могут быть у подчинённых криптоключей, у юзеров. Сразу после создания ключевой пары, у каждого блока в ключе есть только одна подпись, она создана мастер-криптоключом (напомню, что это сделано для того, чтобы можно было безопасно таскать кучку блоков вместе, а целостность — что никто не подменил блок — как раз обеспечивается подписью мастер-криптоключа).

Структуру строк-подписей рассмотрим на примере этой:

uid                  John Smith <js@server.tld>
sig 3        4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>

После слова-маркера sig идёт набор флагов подписи, затем ID криптоключа, которым сделана подпись, далее дата создания подписи, а в конце ID юзера (тут как раз и показывается первичный uid, о котором шла речь чуть выше). Если для данного ID криптоключа в кейринге нет публичного ключа, то вместо строки с информацией о юзере показывается нечто вроде [User ID not found].

Теперь о флагах, для каждого типа флага отведена одна позиция в списке флагов.

sig 3        4600813F 2013-03-11  John Smith (esquire)
    ^^^^^^^
    ||||||| 
    ||||||+- [7] уровень доверия к ключу
    |||||+-- [6] `X`, просроченная подпись
    ||||+--- [5] `N`, в подписи есть Notation
    |||+---- [4] `P`, в подписи указан Policy URL
    ||+----- [3] `R`, неотзываемая подпись
    |+------ [2] `L`, неэкспортируемая подпись 
    +------- [1] (0, 1, 2 или 3) уровень проверки

Что вся эта муть означает, я писать даже и не хочу. Самые важные поля: [1], [6] и [7]. Если установлен флаг [4] (буква P), то значит в подписи есть URL, по которому самые задроты кладут файлик с описанием их морального кодекса подписывания ключей3.

Флаг уровень проверки может содержать 0, 1, 2 или 3, по умолчанию стоит 0. Каждый уровень означает следующее:

0 — нет никакого особого уровня проверки, это значение по умолчанию, вы не думая подписали этот ключ.

1 — это означает, что вы считаете, что ключ принадлежит указанной персоне, но никак это не проверяли.

2 — это означает, что вы предприняли самые минимальные усилия, чтобы удостовериться, что ключ принадлежит указанной персоне.

3 — это означает, что вы прям совсем точно знаете, что ключ принадлежит кому надо.

Для своих собственных юзеров ключа, как вы можете видеть из листинга выше, стоит уровень проверки 3, что в принципе логично. Если вы просто создаёте подпись без указания конкретного уровня, то подразумевается уровень 0.

Вот как можно подписать ключ с уровнем проверки 1 (привожу полный вывод команды):

$ gpg --default-cert-level 1 --sign-key 5B20C7D2

pub  4096R/5B20C7D2  created: 2012-04-18  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  4096R/91AB7DC8  created: 2012-04-18  expires: never       usage: E
[ unknown] (1). Sergey Stolyarov <sergei@regolit.com>
[ revoked] (2)  Sergei Stolyarov <sergei@regolit.com>
[ unknown] (3)  [jpeg image of size 2017]

Really sign all user IDs? (y/N) y
User ID "Sergei Stolyarov <sergei@regolit.com>" is revoked.  Unable to sign.

pub  4096R/5B20C7D2  created: 2012-04-18  expires: never       usage: SC
                     trust: unknown       validity: unknown
 Primary key fingerprint: 87E2 946B 041B CF31 8C4D  5BA7 4695 E635 5B20 C7D2

     Sergey Stolyarov <sergei@regolit.com>
     [jpeg image of size 2017]

Are you sure that you want to sign this key with your
key "John Smith (esquire) <john.smith@example.com>" (4600813F)

I have not checked this key at all.

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "John Smith (esquire) <john.smith@example.com>"
2048-bit RSA key, ID 4600813F, created 2013-03-11

$

Здесь я подписываю свой собственный публичный ключ тестовым ключом, созданным специально для этой статьи. После ввода парольной фразы можно посмотреть, как выглядит набор сигнатур после подписи (напомню, команда --list-sigs):

pub   4096R/5B20C7D2 2012-04-18
uid                  Sergey Stolyarov <sergei@regolit.com>
sig 3        5B20C7D2 2013-03-07  Sergey Stolyarov <sergei@regolit.com>
sig 1        4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>
uid                  [jpeg image of size 2017]
sig 3        5B20C7D2 2012-04-18  Sergey Stolyarov <sergei@regolit.com>
sig 1        4600813F 2013-03-11  John Smith (esquire) <john.smith@example.com>
sub   4096R/91AB7DC8 2012-04-18
sig          5B20C7D2 2012-04-18  Sergey Stolyarov <sergei@regolit.com>

Как видите, к каждому блоку (кроме отозванных) добавлена подпись, созданная ключом с ID 4600813F и уровнем проверки 1.

Полезное дополнительное чтиво


  1. Вообще, команда --list-keys печатает не все блоки для каждого ключа, например, она не выводит подписи, но для общего понимания структуры ключа это не особо важно. 

  2. На самом деле не всех, часть доступных команд в этом списке отсутствует, видимо, они считаются слишком продвинутыми. Пример такой команды — cross-certify, про неё можно тут почитать. 

  3. Посмотреть список этих урлов можно командой gpg --list-sigs --list-options show-policy-urls 

Комментарии

Алексей | 2016-02-10 в 04:19

Спасибо, отличная статья. Может подскажете, как одной командой получить отметку primary uid ключа/ключей? Т.к. количество этих самых uid может быть больше одного и, по моим наблюдениям, primary uid не всегда выводится первым. Явно такой uid отмечается только в режиме редактирования ключа. Особенно интересно в контексте опции --with-colons

| 2016-02-10 в 09:39

Хороший вопрос! В параметрах --list-keys я не нашёл такого, при использовании --with-colons вроде бы primary uid помечается большими буквами в 12 поле:

  1. Field: Key capabilities: e = encrypt s = sign c = certify a = authentication A key may have any combination of them in any order. In addition to these letters, the primary key has uppercase versions of the letters to denote the usable capabilities of the entire key, and a potential letter 'D' to indicate a disabled key.
Алексей | 2016-02-10 в 16:33

the primary key has uppercase versions of the letters

Тут речь про ключ, как я понял. А меня интересует uid, у которого я насчитал всего 11 полей. А еще в документации для первого поля упоминается такое:

uid = user id (only field 10 is used).

Эх, жаль.

Текст комментария (разметка: *курсив*, **полужирная**, [ссылка](http://example.com) или <http://example.com> ещё)
Имя (обязательно, 50 символов или меньше)
Email, на который получать ответы (не будет опубликован)
Веб-сайт
© 2006—2016 Sergey Stolyarov | Работает на Pyrone