PGP ключи в виде QR-кодов
Если хочется сделать hard copy ключа PGP/GPG (что в общем случае может быть хорошей идеей, не забываем про мантру делайбэкапыкаждыйдень), но перспектива при необходимости вбивать посимвольно или возиться с OCR не воодушевляет, на помощь приходят неожиданно QR-коды.
Генерировать QR можно, например, небольшой консольной утилитой
qrencode
. Прочитать QR кроме телефона
можно например утилитой zbar
. Это не очень
интересно. Интереснее оказывается вопрос как закодировать ключ в QR наиболее
эффективным образом.
В принципе, для эллиптических ключей, просто экспорт через gpg --armor
даст
умеренно сносные результаты, i.e. результат уместится в один QR-код. А ключи RSA
вменяемой длины (2048-4096), как их ни сжимай, на один QR-код не влезут.
Тем не менее, эксперименты показали, что двоичное представление ключа (т.е. без
--armor
), ужатое либо lzma
либо zstd
и преобразованное в base32 даёт
наилучшие результаты. Base32 потому что QR-коды наиболее оптимально кодируют
латинские буквы без учёта регистра и цифры, поэтому base64 оказывается в итоге
дороже, несмотря на то что сам текст короче.
Не буду больше тянуть, однострочник такой:
gpg --export-secret-keys <keyid> | lzma | base32 | qrencode -o- -lH -tEPS | lpr
Можно указать несколько ключей, если понизить избыточность (параметр -lL
вместо -lH
), можно уместить по крайней мере 5 эллиптических ключей на один QR.
Но мне несколько претит понижать избыточность без крайней нужды, бумага – не
слишком надёжный носитель.
Понятно, это работает для эллиптических ключей, потому что они короткие. Для длинных – можно использовать т.н. structured QR, т.е. размазывание данных по нескольким QR-кодам. Однострочник тогда примет вид:
gpg --export-secret-keys <keyid> | lzma | base32 | qrencode -ooutput.eps -lH -tEPS -S -v40
Эта команда создаст несколько файлов вида output-nn.eps
, где nn
это номер.
Ключ -S
включает structured QR, -v40
устанавливает максимальный размер для
каждого индивидуального QR-кода. С высокой степенью избыточности (-lH
) можно
уместить 4096-битный ключ на 7 QR-кодах (каждый размером с лист A4), а с низкой
(-lL
) – “всего” на 3-х.
Нюанс в том, что structured QR не так-то просто прочитать обратно. Мне это
удалось только отсканировав распечатки, склеив их в один файл в правильном
порядке и скормив это в zbarimg
. Отдельно отмечу, что фотографии на камеру
телефона оказались недостаточно чёткими, чтобы их потом прочитать (по крайней
мере с -lL
).
Альтернативные варианты для больших ключей:
- Кодировать в формат datamatrix вместо QR, например используя dmtx-utils
- Использовать paperkey чтобы удалить “несекретные” части секретного ключа. Публичный ключ тогда должен быть доступен по каким-то другим каналам, например загружен на серверы ключей и т.п.
Более подробно эти альтернативы рассмотрены, например здесь
Ну и в заключение, я эту технику применил чтобы сделать hard copy, но в общем случае можно аналогичный подход использовать для обмена публичными ключами офлайн – эллиптические публичные ключи тоже достаточно короткие. На правах proof of concept: