User Tools

Site Tools


topic:gpg-pass-git

Хранение паролей с GPG, Pass и GIT

Делаем личную хранилку паролей на своих мощностях, сервисам не доверяем.
Получится не так удобно, но спокойнее.

Компоненты:

  • GPG (GNU Privacy Guard) - программа для шифрования различных файлов.
    Так же gpg может быть использован для подписи файлов, программ или почты.
  • Pass (https://www.passwordstore.org/) - собственно сама программа для хранения паролей, которая для шифрования использует GPG.
  • GIT - используется для синхронизации хранилища с паролями между несколькими машинами.
  • USB flash drive - пару физических флешек в разных квартирах для бэкапа gpg-ключей.

Работа с GPG

Установка

root@e97a5e2d9c78:/# apt install gpg

Генерим ключ

Проверям, что никаких других gpg-ключей нет, смотрим список публичных и приватных ключей.

root@74b608401f03:~# gpg -k
gpg: directory '/root/.gnupg' created
gpg: keybox '/root/.gnupg/pubring.kbx' created
gpg: /root/.gnupg/trustdb.gpg: trustdb created

root@74b608401f03:~# gpg -K

Генерим первый ключ.

root@e97a5e2d9c78:/# gpg --full-gen-key
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: directory '/root/.gnupg' created
gpg: keybox '/root/.gnupg/pubring.kbx' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
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) 
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Ivan Fadin
Email address: if@nomail.if
Comment: GPG_for_Ivan
You selected this USER-ID:
    "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>"

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

Дальше попросит два раза ввести пароль от нового ключа и сделать немного энтропии для генерации.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
nvnlzd
oosdfpsodfmncxscWe need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
poogpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
pagpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/6952D134B31D02DDFDFA87E80BD9EBD6A01F0C63.rev'

Ключи будут лежать в “.gnupg”.

root@e97a5e2d9c78:/# ls -la ~/.gnupg/
total 12
drwx------ 4 root root  207 Oct 14 15:39 .
drwx------ 1 root root   20 Oct 14 15:33 ..
srwx------ 1 root root    0 Oct 14 15:35 S.gpg-agent
srwx------ 1 root root    0 Oct 14 15:35 S.gpg-agent.browser
srwx------ 1 root root    0 Oct 14 15:35 S.gpg-agent.extra
srwx------ 1 root root    0 Oct 14 15:35 S.gpg-agent.ssh
drwx------ 2 root root   58 Oct 14 15:35 openpgp-revocs.d
drwx------ 2 root root  110 Oct 14 15:35 private-keys-v1.d
-rw-r--r-- 1 root root 2482 Oct 14 15:35 pubring.kbx
-rw------- 1 root root   32 Oct 14 15:33 pubring.kbx~
-rw------- 1 root root 1280 Oct 14 15:39 trustdb.gpg

Поднастроить gpg: показывать id ключа.

root@74b608401f03:~# joe ~/.gnupg/gpg.conf
...
keyid-format 0xlong
...

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

root@74b608401f03:~# gpg -k
/root/.gnupg/pubring.kbx
------------------------
pub   rsa4096/0xF6D1FBD02D3BD3E4 2023-10-15 [SC]
      F3E3A9AAACE05FE9AF91B760F6D1FBD02D3BD3E4
uid                   [ultimate] Ivan Fadin (GPG_for_Ivan) <if@nomail.if>
sub   rsa4096/0xE7827AEBA3BB846D 2023-10-15 [E]
root@74b608401f03:~# gpg -K
/root/.gnupg/pubring.kbx
------------------------
sec   rsa4096/0xF6D1FBD02D3BD3E4 2023-10-15 [SC]
      F3E3A9AAACE05FE9AF91B760F6D1FBD02D3BD3E4
uid                   [ultimate] Ivan Fadin (GPG_for_Ivan) <if@nomail.if>
ssb   rsa4096/0xE7827AEBA3BB846D 2023-10-15 [E]

Зашифровать файл

Есть файл f1.txt с текстом.

root@e97a5e2d9c78:~/test_area# ll
total 8
-rw-r--r-- 1 root root  10 Oct 14 15:48 f1.txt

root@e97a5e2d9c78:~/test_area# cat f1.txt
Some Text

Шифруем файл командой “gpg -e -a -r”, где:

  • -e - зашифровать.
  • -a - на выходе аски текст.
  • -к - ключ, с помощью которого шифровать.
    В данном примере ключ указывается через “комментарий”, так же можно через id или через почту.
root@e97a5e2d9c78:~/test_area# gpg -e -a -r GPG_for_Ivan f1.txt

root@e97a5e2d9c78:~/test_area# ll
total 8
-rw-r--r-- 1 root root  10 Oct 14 15:48 f1.txt
-rw-r--r-- 1 root root 882 Oct 14 15:54 f1.txt.asc

root@e97a5e2d9c78:~/test_area# cat f1.txt.asc 
-----BEGIN PGP MESSAGE-----

hQIMA21KbFqg3TnaAQ//as6/JKBOPVqJWTmb54nsdonR3z2o+MbWWs0EpW3rjTw6
iRensJac297n9n1rVdwpOMOBU1d3bOdM/EXbzcTtcldmx26jylSKUXNpOTPnktiE
kK2ZXgdCxdcSzt+DcuRw7+MchgrdHysPUpt3rL6ic54EZPvp3oPTADsVMapr4YoM
OwyIqIv76xa30aUgvf85gBCiyWrRcMI0zM5oA9e3sUN7UVAfdydiuRwbPhoqF3+s
5XVQPbDM6J2i86ttqIqDhVp21werhBdbnIvWDJ3ilnLQEq8eBX72KZK6Xlu8Macb
0AIkjkC4uu4M0VYMTTd1l/tkb2Ok9M1ZIB09CxUIkVU61YA0ox/aeHC3GR8cczaq
gYVnpG64Dk6Fq4x5u5QU3zLWw/VkveBqaLiQTC4cLocSUxH2ueq385XQXNZbZoRG
tLma0sMX+InMOSixRS5hZe/Ur9hVgC1DVlILppTUBiWeR7xq3V7hugrJPIdYX6qf
kg7io/wQmYT2R+1mz4D8V50f4WDzOTOjpLNlo06iCVTfhyaDZ7AgaVgdMQxfMcev
Jv9Bra7+MDq18fs3kuhzwbSyExoPN4cB09U8QLS7otph2WHXqpTUQayfy0mcxEIq
ND50SEOr3OY0m1UtezmbKci3aL4tqvUkwNAQB9oLrgqUGjjSnIu7diG4lFTCReLS
SwFEWJ2N8iQyA/JQ0c+HmMSEzFUEn04gW/J/xx6cZRZbzTRciojmoc0NIqwyUYtp
r0tQRp6BZnFzt0t+IUSYJ/uEfZYRgzOsC6BH7g==
=N58t
-----END PGP MESSAGE-----
root@e97a5e2d9c78:~/test_area# 

Расшифровать файл

Расшифруем файл командой “gpg -d -o”, где:

  • -d - расшифровать.
  • -o - выходной файл.
root@e97a5e2d9c78:~/test_area# gpg -d -o f2.txt f1.txt.asc 
gpg: encrypted with 4096-bit RSA key, ID 0x6D4A6C5AA0DD39DA, created 2023-10-14
      "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>"

root@e97a5e2d9c78:~/test_area# ll
total 8
-rw-r--r-- 1 root root 882 Oct 14 15:54 f1.txt.asc
-rw-r--r-- 1 root root  10 Oct 14 15:58 f2.txt

root@e97a5e2d9c78:~/test_area# cat f2.txt 
Some Text
root@e97a5e2d9c78:~/test_area# 

Работы с ключами

Экспорт ключей

root@74b608401f03:~/gpg_bup# gpg --export -a if@nomail.if > ivan_main_gpg_public_20231015.pgp
root@74b608401f03:~/gpg_bup# gpg --export-secret-key -a if@nomail.if > ivan_main_gpg_secret_20231015.pgp

root@74b608401f03:~/gpg_bup# ll
total 12
-rw-r--r-- 1 root root 3143 Oct 15 08:17 ivan_main_gpg_public_20231015.pgp
-rw-r--r-- 1 root root 6764 Oct 15 08:18 ivan_main_gpg_secret_20231015.pgp

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

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


Удалить ключи

root@74b608401f03:~# gpg --delete-secret-key if@nomail.if
root@74b608401f03:~# gpg --delete-keys if@nomail.if

При удалении приватного ключа, спрашивает аж три раза.


Ипортировать ключи

root@74b608401f03:~/gpg_bup# ll
total 12
-rw-r--r-- 1 root root 3143 Oct 15 08:17 ivan_main_gpg_public_20231015.pgp
-rw-r--r-- 1 root root 6764 Oct 15 08:18 ivan_main_gpg_secret_20231015.pgp

root@74b608401f03:~/gpg_bup# gpg --import ivan_main_gpg_public_20231015.pgp 
gpg: key 0xF6D1FBD02D3BD3E4: public key "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>" imported
gpg: Total number processed: 1
gpg:               imported: 1

root@74b608401f03:~/gpg_bup# gpg --import ivan_main_gpg_secret_20231015.pgp 
gpg: key 0xF6D1FBD02D3BD3E4: "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>" not changed
gpg: key 0xF6D1FBD02D3BD3E4: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

При импорте приватного ключа спросит пароль.


Поменять пароль на ключе

root@e97a5e2d9c78:~/test_area# gpg --edit-key GPG_for_Ivan
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH
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.

sec  rsa4096/0BD9EBD6A01F0C63
     created: 2023-10-14  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa4096/6D4A6C5AA0DD39DA
     created: 2023-10-14  expires: never       usage: E   
[ultimate] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if>

gpg> passwd

gpg> save
Key not changed so no update needed.

После команды passwd спросят текущий пароль и два раза новый пароль.


Действия после импорта ключей

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

root@74b608401f03:~/test_area# gpg -e -a -r GPG_for_Ivan f1.txt 
gpg: 0xE7827AEBA3BB846D: There is no assurance this key belongs to the named user

sub  rsa4096/0xE7827AEBA3BB846D 2023-10-15 Ivan Fadin (GPG_for_Ivan) <if@nomail.if>
 Primary key fingerprint: F3E3 A9AA ACE0 5FE9 AF91  B760 F6D1 FBD0 2D3B D3E4
      Subkey fingerprint: 7AFC 4254 BA3D 6F1F 8A5A  A177 E782 7AEB A3BB 846D

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) y

Надо пометить ключ как trust.

root@74b608401f03:~/test_area# gpg --edit-key F6D1FBD02D3BD3E4
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH
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.

sec  rsa4096/0xF6D1FBD02D3BD3E4
     created: 2023-10-15  expires: never       usage: SC  
     trust: unknown       validity: unknown
ssb  rsa4096/0xE7827AEBA3BB846D
     created: 2023-10-15  expires: never       usage: E   
[ unknown] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if>

gpg> trust
sec  rsa4096/0xF6D1FBD02D3BD3E4
     created: 2023-10-15  expires: never       usage: SC  
     trust: unknown       validity: unknown
ssb  rsa4096/0xE7827AEBA3BB846D
     created: 2023-10-15  expires: never       usage: E   
[ unknown] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if>

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

sec  rsa4096/0xF6D1FBD02D3BD3E4
     created: 2023-10-15  expires: never       usage: SC  
     trust: ultimate      validity: unknown
ssb  rsa4096/0xE7827AEBA3BB846D
     created: 2023-10-15  expires: never       usage: E   
[ unknown] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if>
Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg> save
Key not changed so no update needed.

Работа с pass

Установка

root@84abb3771ecc:~# apt install pass
root@84abb3771ecc:~# which pass
/usr/bin/pass

Инициализация хранилища pass

Хранилище создается с привязкой к id gpg-ключа (id, почта или коммент).

root@84abb3771ecc:~# pass init GPG_for_Ivan
mkdir: created directory '/root/.password-store/'
Password store initialized for GPG_for_Ivan

По дефолту хранилище создаётся в домашней папке пользователя в скрытой папке “.password-store”.
В файле “~/..password-store/.gpg-id” список id привязанных к хранилищу ключей.


Работа с паролями

Записать пароль в одну строку

root@84abb3771ecc:~# pass insert work/one-password 
Enter password for work/one-password: 
Retype password for work/one-password: 

Записать пароль в несколько строк

root@84abb3771ecc:~# pass insert another-work/m-lines-password -m
mkdir: created directory '/root/.password-store/another-work'
Enter contents of another-work/m-lines-password and press Ctrl+D when finished:

login = user1
password = blabla-pass

Сгенерить пароль автоматически

root@84abb3771ecc:~# pass generate work/gen-pass
The generated password for work/gen-pass is:
G+5%sH$pk-{+kf=8bKEzh2i6b
root@84abb3771ecc:~# pass work/gen-pass
G+5%sH$pk-{+kf=8bKEzh2i6b

Посмотреть пароль

Посмотреть структуру хранилища.

root@84abb3771ecc:~# pass
Password Store
|-- another-work
|   `-- m-lines-password
`-- work
    |-- gen-pass
    `-- one-password

Посмотреть конкретный пароль.

root@84abb3771ecc:~# pass work/one-password
blabla

Спросит пароль от gpg-ключа.

Удалить пароль

root@84abb3771ecc:~# pass rm work/gen-pass
Are you sure you would like to delete work/gen-pass? [y/N] y
removed '/root/.password-store/work/gen-pass.gpg'

Содержимое файлов c паролями

root@84abb3771ecc:~# tree ~/.password-store/
/root/.password-store/
|-- another-work
|   `-- m-lines-password.gpg
`-- work
    `-- one-password.gpg

3 directories, 2 files

root@84abb3771ecc:~# cat ~/.password-store/work/one-password.gpg 
�
Ƒ*L1Ľ���$,���tn(۩������F���B��)�iF��W��v,��p�yT�j�f!���v�o��R̙d���

��q�۞��=w�	q����	����f�[:�7��B�^�u�����GD�  < 

��"Q �*E���r�C���S�a���ҵMI\A��

root@84abb3771ecc:~#

Интеграцияя pass с git

Pass умеет работать с git.

Для примера будем использовать github, по хорошему надо не публичный git использовать.
Заводим на github приватный репозиторий (ssh: git@github.com:if473/test-pass.git) и копируем наш публичный ssh-ключ.

Делаем начальную настройку git на машине с pass.

root@84abb3771ecc:~# git config --global user.email "if@nomail.if"
root@84abb3771ecc:~# git config --global user.name "Ivan Fadin"

Инициализируем git в хранилище.

root@84abb3771ecc:~# pass git init
Initialized empty Git repository in /root/.password-store/.git/

Указываем pass на репозиторий в github.

root@84abb3771ecc:~# pass git remote add origin git@github.com:if473/test-pass.git

Настройки git.

root@84abb3771ecc:~# cat .password-store/.git/config 
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[diff "gpg"]
	binary = true
	textconv = gpg -d --quiet --yes --compress-algo=none --no-encrypt-to
[remote "origin"]
	url = git@github.com:if473/test-pass.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master

Первый коммит.

root@84abb3771ecc:~/.password-store# git add .  

root@84abb3771ecc:~/.password-store# git commit -m "20231015 new pass"
[master (root-commit) 3519549] 20231015 new pass
 4 files changed, 2 insertions(+)
 create mode 100644 .gitattributes
 create mode 100644 .gpg-id
 create mode 100644 another-work/m-lines-password.gpg
 create mode 100644 work/one-password.gpg

root@84abb3771ecc:~/.password-store# git push origin master
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (8/8), 1.65 KiB | 842.00 KiB/s, done.
Total 8 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:if473/test-pass.git
 * [new branch]      master -> master

Последующие коммиты, после добавление нового пароля.

root@84abb3771ecc:~# pass insert work/diff-pass-3
Enter password for work/diff-pass-3: 
Retype password for work/diff-pass-3: 

[master ad1fd86] Add given password for work/diff-pass-3 to store.
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 work/diff-pass-3.gpg

root@84abb3771ecc:~# pass git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 929 bytes | 929.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:if473/test-pass.git
   64b0e39..ad1fd86  master -> master

Полезные ссылки

topic/gpg-pass-git.txt · Last modified: 2023/10/15 21:48 by k

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki