mirror of
https://github.com/sunknudsen/privacy-guides.git
synced 2025-02-22 16:53:56 +00:00
Implemented Shamir Secret Sharing feature
This commit is contained in:
parent
81246f8000
commit
4b0273549f
@ -2,7 +2,7 @@
|
||||
Title: How to create encrypted paper backup
|
||||
Description: Learn how to create encrypted paper backup.
|
||||
Author: Sun Knudsen <https://github.com/sunknudsen>
|
||||
Contributors: Sun Knudsen <https://github.com/sunknudsen>, Alex Anderson <https://github.com/Serpent27>, Nico Kaiser <https://github.com/nicokaiser>
|
||||
Contributors: Sun Knudsen <https://github.com/sunknudsen>, Alex Anderson <https://github.com/Serpent27>, Nico Kaiser <https://github.com/nicokaiser>, Daan Sprenkels<https://github.com/dsprenkels>
|
||||
Reviewers:
|
||||
Publication date: 2021-02-23T21:53:38.495Z
|
||||
Listed: false
|
||||
@ -80,12 +80,12 @@ sudo raspi-config
|
||||
|
||||
Select “Localisation Options”, then “Keyboard”, then “Generic 105-key PC (intl.)”, then “Other”, then “English (US)”, then “English (US)”, then “The default for the keyboard layout”, then “No compose key” and finally “Finish”.
|
||||
|
||||
### Step 4: install dependencies
|
||||
### Step 4: install dependencies available on repositories
|
||||
|
||||
```console
|
||||
$ sudo apt update
|
||||
|
||||
$ sudo apt install -y fim imagemagick zbar-tools
|
||||
$ sudo apt install -y fim imagemagick
|
||||
|
||||
$ pip3 install mnemonic pillow qrcode --user
|
||||
|
||||
@ -94,12 +94,149 @@ $ echo -e "export GPG_TTY=\"\$(tty)\"\nexport PATH=\$PATH:/home/pi/.local/bin" >
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
### Step 5 (optional): install [Electrum](https://electrum.org/#home) (required to generate Electrum mnemonic)
|
||||
### Step 5: install [zbar](https://github.com/mchehab/zbar) from source
|
||||
|
||||
#### Install zbar dependencies
|
||||
|
||||
```console
|
||||
$ sudo apt update
|
||||
|
||||
$ sudo apt install -y autopoint build-essential git libv4l-dev libtool
|
||||
```
|
||||
|
||||
#### Clone zbar repository
|
||||
|
||||
```console
|
||||
$ cd ~
|
||||
|
||||
$ git clone https://github.com/mchehab/zbar
|
||||
|
||||
$ cd zbar
|
||||
|
||||
$ git checkout 0.23.90
|
||||
```
|
||||
|
||||
#### Configure, compile and install zbar
|
||||
|
||||
```console
|
||||
$ autoreconf -vfi
|
||||
|
||||
$ ./configure --without-python
|
||||
|
||||
$ make
|
||||
|
||||
$ sudo make install
|
||||
|
||||
$ sudo ldconfig
|
||||
|
||||
$ rm -fr ~/zbar
|
||||
```
|
||||
|
||||
### Step 6: install [sss-cli](https://github.com/dsprenkels/sss-cli) from source
|
||||
|
||||
#### Install [Rust](https://www.rust-lang.org/)
|
||||
|
||||
```console
|
||||
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
info: downloading installer
|
||||
|
||||
Welcome to Rust!
|
||||
|
||||
This will download and install the official compiler for the Rust
|
||||
programming language, and its package manager, Cargo.
|
||||
|
||||
Rustup metadata and toolchains will be installed into the Rustup
|
||||
home directory, located at:
|
||||
|
||||
/home/pi/.rustup
|
||||
|
||||
This can be modified with the RUSTUP_HOME environment variable.
|
||||
|
||||
The Cargo home directory located at:
|
||||
|
||||
/home/pi/.cargo
|
||||
|
||||
This can be modified with the CARGO_HOME environment variable.
|
||||
|
||||
The cargo, rustc, rustup and other commands will be added to
|
||||
Cargo's bin directory, located at:
|
||||
|
||||
/home/pi/.cargo/bin
|
||||
|
||||
This path will then be added to your PATH environment variable by
|
||||
modifying the profile files located at:
|
||||
|
||||
/home/pi/.profile
|
||||
/home/pi/.bashrc
|
||||
|
||||
You can uninstall at any time with rustup self uninstall and
|
||||
these changes will be reverted.
|
||||
|
||||
Current installation options:
|
||||
|
||||
|
||||
default host triple: armv7-unknown-linux-gnueabihf
|
||||
default toolchain: stable (default)
|
||||
profile: default
|
||||
modify PATH variable: yes
|
||||
|
||||
1) Proceed with installation (default)
|
||||
2) Customize installation
|
||||
3) Cancel installation
|
||||
>1
|
||||
|
||||
info: profile set to 'default'
|
||||
info: default host triple is armv7-unknown-linux-gnueabihf
|
||||
info: syncing channel updates for 'stable-armv7-unknown-linux-gnueabihf'
|
||||
info: latest update on 2021-03-25, rust version 1.51.0 (2fd73fabe 2021-03-23)
|
||||
info: downloading component 'cargo'
|
||||
info: downloading component 'clippy'
|
||||
info: downloading component 'rust-std'
|
||||
19.6 MiB / 19.6 MiB (100 %) 11.0 MiB/s in 2s ETA: 0s
|
||||
info: downloading component 'rustc'
|
||||
81.9 MiB / 81.9 MiB (100 %) 10.6 MiB/s in 10s ETA: 0s
|
||||
info: downloading component 'rustfmt'
|
||||
info: installing component 'cargo'
|
||||
info: using up to 500.0 MiB of RAM to unpack components
|
||||
5.5 MiB / 5.5 MiB (100 %) 3.5 MiB/s in 1s ETA: 0s
|
||||
info: installing component 'clippy'
|
||||
info: installing component 'rust-std'
|
||||
19.6 MiB / 19.6 MiB (100 %) 3.1 MiB/s in 6s ETA: 0s
|
||||
info: installing component 'rustc'
|
||||
81.9 MiB / 81.9 MiB (100 %) 3.0 MiB/s in 33s ETA: 0s
|
||||
info: installing component 'rustfmt'
|
||||
3.3 MiB / 3.3 MiB (100 %) 3.1 MiB/s in 2s ETA: 0s
|
||||
info: default toolchain set to 'stable-armv7-unknown-linux-gnueabihf'
|
||||
|
||||
stable-armv7-unknown-linux-gnueabihf installed - rustc 1.51.0 (2fd73fabe 2021-03-23)
|
||||
|
||||
|
||||
Rust is installed now. Great!
|
||||
|
||||
To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH
|
||||
environment variable. Next time you log in this will be done
|
||||
automatically.
|
||||
|
||||
To configure your current shell, run:
|
||||
source $HOME/.cargo/env
|
||||
```
|
||||
|
||||
#### Install sss-cli
|
||||
|
||||
```console
|
||||
$ cd ~
|
||||
|
||||
$ cargo install --git https://github.com/dsprenkels/sss-cli --branch v0.1
|
||||
|
||||
$ cp ~/.cargo/bin/secret-share* ~/.local/bin/
|
||||
```
|
||||
|
||||
### Step 7 (optional): install [Electrum](https://electrum.org/#home) (required to generate Electrum mnemonic)
|
||||
|
||||
#### Install Electrum dependencies
|
||||
|
||||
```shell
|
||||
apt install -y libsecp256k1-0 python3-cryptography
|
||||
sudo apt install -y libsecp256k1-0 python3-cryptography
|
||||
```
|
||||
|
||||
#### Set Electrum release semver environment variable
|
||||
@ -159,7 +296,7 @@ Good signature
|
||||
pip3 install --user Electrum-$ELECTRUM_RELEASE_SEMVER.tar.gz
|
||||
```
|
||||
|
||||
### Step 6 (optional): install `screen` and [trezorcrl](https://wiki.trezor.io/Using_trezorctl_commands_with_Trezor) (required to validate integrity of [Trezor](https://trezor.io/) encrypted paper backups)
|
||||
### Step 8 (optional): install `screen` and [trezorcrl](https://wiki.trezor.io/Using_trezorctl_commands_with_Trezor) (required to validate integrity of [Trezor](https://trezor.io/) encrypted paper backups)
|
||||
|
||||
```console
|
||||
$ sudo apt install -y screen
|
||||
@ -169,47 +306,227 @@ $ pip3 install attrs trezor --user
|
||||
$ sudo curl https://data.trezor.io/udev/51-trezor.rules -o /etc/udev/rules.d/51-trezor.rules
|
||||
```
|
||||
|
||||
### Step 7: download [create-bip39-mnemonic.py](./create-bip39-mnemonic.py) ([PGP signature](./create-bip39-mnemonic.py.sig), [PGP public key](https://sunknudsen.com/sunknudsen.asc))
|
||||
### Step 9: import Sun’s PGP public key (used to verify downloads bellow)
|
||||
|
||||
```shell
|
||||
sudo curl -o /usr/local/sbin/create-bip39-mnemonic.py https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/create-bip39-mnemonic.py
|
||||
```console
|
||||
$ curl https://sunknudsen.com/sunknudsen.asc | gpg --import
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 6896 100 6896 0 0 6499 0 0:00:01 0:00:01 --:--:-- 6499
|
||||
gpg: key C1323A377DE14C8B: public key "Sun Knudsen <hello@sunknudsen.com>" imported
|
||||
gpg: Total number processed: 1
|
||||
gpg: imported: 1
|
||||
```
|
||||
|
||||
### Step 8: download [validate-bip39-mnemonic.py](./validate-bip39-mnemonic.py) ([PGP signature](./validate-bip39-mnemonic.py.sig), [PGP public key](https://sunknudsen.com/sunknudsen.asc))
|
||||
imported: 1
|
||||
|
||||
```shell
|
||||
sudo curl -o /usr/local/sbin/validate-bip39-mnemonic.py https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/validate-bip39-mnemonic.py
|
||||
👍
|
||||
|
||||
### Step 10: download and verify [create-bip39-mnemonic.py](./create-bip39-mnemonic.py)
|
||||
|
||||
```console
|
||||
$ curl -o /home/pi/.local/bin/create-bip39-mnemonic.py https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/create-bip39-mnemonic.py
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 149 100 149 0 0 138 0 0:00:01 0:00:01 --:--:-- 138
|
||||
|
||||
$ curl -o /home/pi/.local/bin/create-bip39-mnemonic.py.sig https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/create-bip39-mnemonic.py.sig
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 833 100 833 0 0 681 0 0:00:01 0:00:01 --:--:-- 681
|
||||
|
||||
$ gpg --verify /home/pi/.local/bin/create-bip39-mnemonic.py.sig
|
||||
gpg: assuming signed data in '/home/pi/.local/bin/create-bip39-mnemonic.py'
|
||||
gpg: Signature made Fri 09 Apr 2021 13:53:03 EDT
|
||||
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
|
||||
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
|
||||
Subkey fingerprint: A98C CD12 2243 655B 26FA FB61 1FA7 6786 2BBD 1305
|
||||
|
||||
$ chmod 600 /home/pi/.local/bin/create-bip39-mnemonic.py
|
||||
```
|
||||
|
||||
### Step 9: download [qr-backup.sh](./qr-backup.sh) ([PGP signature](./qr-backup.sh.sig), [PGP public key](https://sunknudsen.com/sunknudsen.asc))
|
||||
Primary key fingerprint matches [published](../how-to-encrypt-sign-and-decrypt-messages-using-gnupg-on-macos#verify-suns-pgp-public-key-using-its-fingerprint) fingerprints
|
||||
|
||||
```shell
|
||||
sudo curl -o /usr/local/sbin/qr-backup.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-backup.sh
|
||||
sudo chmod +x /usr/local/sbin/qr-backup.sh
|
||||
👍
|
||||
|
||||
Good signature
|
||||
|
||||
👍
|
||||
|
||||
### Step 11: download and verify [validate-bip39-mnemonic.py](./validate-bip39-mnemonic.py)
|
||||
|
||||
```console
|
||||
$ curl -o /home/pi/.local/bin/validate-bip39-mnemonic.py https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/validate-bip39-mnemonic.py
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 6217 100 6217 0 0 8234 0 --:--:-- --:--:-- --:--:-- 8234
|
||||
|
||||
$ curl -o /home/pi/.local/bin/validate-bip39-mnemonic.py.sig https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/validate-bip39-mnemonic.py.sig
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 6217 100 6217 0 0 10361 0 --:--:-- --:--:-- --:--:-- 10344
|
||||
|
||||
$ gpg --verify /home/pi/.local/bin/create-bip39-mnemonic.py.sig
|
||||
gpg: assuming signed data in '/home/pi/.local/bin/create-bip39-mnemonic.py'
|
||||
gpg: Signature made Fri 09 Apr 2021 13:53:03 EDT
|
||||
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
|
||||
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
|
||||
Subkey fingerprint: A98C CD12 2243 655B 26FA FB61 1FA7 6786 2BBD 1305
|
||||
|
||||
$ chmod 600 /home/pi/.local/bin/validate-bip39-mnemonic.py
|
||||
```
|
||||
|
||||
### Step 10: download [qr-restore.sh](./qr-restore.sh) ([PGP signature](./qr-restore.sh.sig), [PGP public key](https://sunknudsen.com/sunknudsen.asc))
|
||||
Primary key fingerprint matches [published](../how-to-encrypt-sign-and-decrypt-messages-using-gnupg-on-macos#verify-suns-pgp-public-key-using-its-fingerprint) fingerprints
|
||||
|
||||
```shell
|
||||
sudo curl -o /usr/local/sbin/qr-restore.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-restore.sh
|
||||
sudo chmod +x /usr/local/sbin/qr-restore.sh
|
||||
👍
|
||||
|
||||
Good signature
|
||||
|
||||
👍
|
||||
|
||||
### Step 12: download and verify [qr-backup.sh](./qr-backup.sh)
|
||||
|
||||
```console
|
||||
$ curl -o /home/pi/.local/bin/qr-backup.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-backup.sh
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 3956 100 3956 0 0 3971 0 --:--:-- --:--:-- --:--:-- 3967
|
||||
|
||||
$ curl -o /home/pi/.local/bin/qr-backup.sh.sig https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-backup.sh.sig
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 833 100 833 0 0 620 0 0:00:01 0:00:01 --:--:-- 620
|
||||
|
||||
$ gpg --verify /home/pi/.local/bin/qr-backup.sh.sig
|
||||
gpg: assuming signed data in '/home/pi/.local/bin/qr-backup.sh'
|
||||
gpg: Signature made Fri 09 Apr 2021 13:52:01 EDT
|
||||
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
|
||||
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
|
||||
Subkey fingerprint: A98C CD12 2243 655B 26FA FB61 1FA7 6786 2BBD 1305
|
||||
|
||||
$ chmod 700 /home/pi/.local/bin/qr-backup.sh
|
||||
```
|
||||
|
||||
### Step 11: download [qr-clone.sh](./qr-clone.sh) ([PGP signature](./qr-clone.sh.sig), [PGP public key](https://sunknudsen.com/sunknudsen.asc))
|
||||
Primary key fingerprint matches [published](../how-to-encrypt-sign-and-decrypt-messages-using-gnupg-on-macos#verify-suns-pgp-public-key-using-its-fingerprint) fingerprints
|
||||
|
||||
```shell
|
||||
sudo curl -o /usr/local/sbin/qr-clone.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-clone.sh
|
||||
sudo chmod +x /usr/local/sbin/qr-clone.sh
|
||||
👍
|
||||
|
||||
Good signature
|
||||
|
||||
👍
|
||||
|
||||
### Step 13: download and verify [qr-restore.sh](./qr-restore.sh)
|
||||
|
||||
```console
|
||||
$ curl -o /home/pi/.local/bin/qr-restore.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-restore.sh
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 1904 100 1904 0 0 1715 0 0:00:01 0:00:01 --:--:-- 1715
|
||||
|
||||
$ curl -o /home/pi/.local/bin/qr-restore.sh.sig https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-restore.sh.sig
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 833 100 833 0 0 908 0 --:--:-- --:--:-- --:--:-- 908
|
||||
|
||||
$ gpg --verify /home/pi/.local/bin/qr-restore.sh.sig
|
||||
gpg: assuming signed data in '/home/pi/.local/bin/qr-restore.sh'
|
||||
gpg: Signature made Fri 09 Apr 2021 13:52:34 EDT
|
||||
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
|
||||
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
|
||||
Subkey fingerprint: A98C CD12 2243 655B 26FA FB61 1FA7 6786 2BBD 1305
|
||||
|
||||
$ chmod 700 /home/pi/.local/bin/qr-restore.sh
|
||||
```
|
||||
|
||||
### Step 12: download [secure-erase.sh](./secure-erase.sh) ([PGP signature](./secure-erase.sh.sig), [PGP public key](https://sunknudsen.com/sunknudsen.asc))
|
||||
Primary key fingerprint matches [published](../how-to-encrypt-sign-and-decrypt-messages-using-gnupg-on-macos#verify-suns-pgp-public-key-using-its-fingerprint) fingerprints
|
||||
|
||||
```shell
|
||||
sudo curl -o /usr/local/sbin/secure-erase.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/secure-erase.sh
|
||||
sudo chmod +x /usr/local/sbin/secure-erase.sh
|
||||
👍
|
||||
|
||||
Good signature
|
||||
|
||||
👍
|
||||
|
||||
### Step 14: download and verify [qr-clone.sh](./qr-clone.sh)
|
||||
|
||||
```console
|
||||
$ curl -o /home/pi/.local/bin/qr-clone.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-clone.sh
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 481 100 481 0 0 440 0 0:00:01 0:00:01 --:--:-- 440
|
||||
|
||||
$ curl -o /home/pi/.local/bin/qr-clone.sh.sig https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-clone.sh.sig
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 833 100 833 0 0 783 0 0:00:01 0:00:01 --:--:-- 784
|
||||
|
||||
$ gpg --verify /home/pi/.local/bin/qr-clone.sh.sig
|
||||
gpg: assuming signed data in '/home/pi/.local/bin/qr-clone.sh'
|
||||
gpg: Signature made Fri 09 Apr 2021 13:52:14 EDT
|
||||
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
|
||||
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
|
||||
Subkey fingerprint: A98C CD12 2243 655B 26FA FB61 1FA7 6786 2BBD 1305
|
||||
|
||||
$ chmod 700 /home/pi/.local/bin/qr-clone.sh
|
||||
```
|
||||
|
||||
### Step 13: make filesystem read-only
|
||||
Primary key fingerprint matches [published](../how-to-encrypt-sign-and-decrypt-messages-using-gnupg-on-macos#verify-suns-pgp-public-key-using-its-fingerprint) fingerprints
|
||||
|
||||
👍
|
||||
|
||||
Good signature
|
||||
|
||||
👍
|
||||
|
||||
### Step 15: download and verify [secure-erase.sh](./secure-erase.sh)
|
||||
|
||||
```console
|
||||
$ curl -o /home/pi/.local/bin/secure-erase.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/secure-erase.sh
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 1283 100 1283 0 0 1189 0 0:00:01 0:00:01 --:--:-- 1189
|
||||
|
||||
$ curl -o /home/pi/.local/bin/secure-erase.sh.sig https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/secure-erase.sh.sig
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 833 100 833 0 0 944 0 --:--:-- --:--:-- --:--:-- 944
|
||||
|
||||
$ gpg --verify /home/pi/.local/bin/secure-erase.sh.sig
|
||||
gpg: assuming signed data in '/home/pi/.local/bin/secure-erase.sh'
|
||||
gpg: Signature made Fri 09 Apr 2021 13:52:46 EDT
|
||||
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
|
||||
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
|
||||
Subkey fingerprint: A98C CD12 2243 655B 26FA FB61 1FA7 6786 2BBD 1305
|
||||
|
||||
$ chmod 700 /home/pi/.local/bin/secure-erase.sh
|
||||
```
|
||||
|
||||
Primary key fingerprint matches [published](../how-to-encrypt-sign-and-decrypt-messages-using-gnupg-on-macos#verify-suns-pgp-public-key-using-its-fingerprint) fingerprints
|
||||
|
||||
👍
|
||||
|
||||
Good signature
|
||||
|
||||
👍
|
||||
|
||||
### Step 16: make filesystem read-only
|
||||
|
||||
> Heads-up: shout-out to Nico Kaiser for his amazing [guide](https://gist.github.com/nicokaiser/08aa5b7b3958f171cf61549b70e8a34b) on how to configure a read-only Raspberry Pi.
|
||||
|
||||
@ -273,13 +590,13 @@ sudo sed -i -e 's/vfat\s*defaults\s/vfat defaults,ro/' /etc/fstab
|
||||
sudo sed -i -e 's/ext4\s*defaults,noatime\s/ext4 defaults,noatime,ro,noload/' /etc/fstab
|
||||
```
|
||||
|
||||
### Step 14: disable Wi-Fi (if not using ethernet)
|
||||
### Step 17: disable Wi-Fi (if not using ethernet)
|
||||
|
||||
```shell
|
||||
echo "dtoverlay=disable-wifi" | sudo tee -a /boot/config.txt
|
||||
```
|
||||
|
||||
### Step 15: disable `dhcpcd`, `networking` and `wpa_supplicant` services and “fix” `rfkill` bug
|
||||
### Step 18: disable `dhcpcd`, `networking` and `wpa_supplicant` services and “fix” `rfkill` bug
|
||||
|
||||
```console
|
||||
$ sudo systemctl disable dhcpcd networking wpa_supplicant
|
||||
@ -287,13 +604,13 @@ $ sudo systemctl disable dhcpcd networking wpa_supplicant
|
||||
$ sudo rm /etc/profile.d/wifi-check.sh
|
||||
```
|
||||
|
||||
### Step 16: delete macOS hidden files (if present)
|
||||
### Step 19: delete macOS hidden files (if present)
|
||||
|
||||
```shell
|
||||
sudo rm -fr /boot/.fseventsd /boot/.DS_Store /boot/.Spotlight-V100
|
||||
```
|
||||
|
||||
### Step 17: reboot
|
||||
### Step 20: reboot
|
||||
|
||||
```shell
|
||||
sudo systemctl reboot
|
||||
@ -301,7 +618,7 @@ sudo systemctl reboot
|
||||
|
||||
> WARNING: DO NOT CONNECT RASPBERRY PI TO NETWORK EVER AGAIN WITHOUT REINSTALLING RASPBERRY PI OS FIRST (DEVICE IS NOW "READ-ONLY" AND “COLD”).
|
||||
|
||||
### Step 18 (optional): disable auto-mount of `boot` volume (on macOS)
|
||||
### Step 21 (optional): disable auto-mount of `boot` volume (on macOS)
|
||||
|
||||
> Heads-up: done to prevent macOS from writing [hidden files](#step-16-delete-macos-hidden-files-if-present) to `boot` volume which would invalidate stored SHA512 hash of micro SD card.
|
||||
|
||||
@ -313,7 +630,7 @@ volume_uuid=$(diskutil info "$volume_path" | awk '/Volume UUID:/ { print $3 }')
|
||||
echo "UUID=$volume_uuid none msdos rw,noauto" | sudo tee -a /etc/fstab
|
||||
```
|
||||
|
||||
### Step 19 (optional): compute SHA512 hash of micro SD card and store in password manager (on macOS)
|
||||
### Step 22 (optional): compute SHA512 hash of micro SD card and store in password manager (on macOS)
|
||||
|
||||
Run `diskutil list` to find disk ID of micro SD card with “Raspberry Pi OS Lite” installed (`disk2` in the following example).
|
||||
|
||||
@ -364,6 +681,11 @@ Options:
|
||||
--create-bip39-mnemonic create BIP39 mnemonic
|
||||
--create-electrum-mnemonic create Electrum mnemonic
|
||||
--validate-bip39-mnemonic validate if secret is valid BIP39 mnemonic
|
||||
--shamir-secret-sharing split secret using Shamir Secret Sharing
|
||||
--number-of-shares number of shares (defaults to 5)
|
||||
--share-threshold shares required to access secret (defaults to 3)
|
||||
--no-encryption disable symmetric encryption (shamir-only)
|
||||
--no-qr disable “Show SHA512 hash as QR code”
|
||||
--label <label> print label after short hash
|
||||
-h, --help display help for command
|
||||
|
||||
@ -403,8 +725,10 @@ $ qr-restore.sh --help
|
||||
Usage: qr-restore.sh [options]
|
||||
|
||||
Options:
|
||||
--word-list split secret into word list
|
||||
-h, --help display help for command
|
||||
--shamir-secret-sharing split secret using Shamir Secret Sharing
|
||||
--share-threshold shares required to access secret (defaults to 3)
|
||||
--word-list split secret into word list
|
||||
-h, --help display help for command
|
||||
|
||||
$ qr-restore.sh
|
||||
Scan QR code…
|
||||
|
0
how-to-create-encrypted-paper-backup/create-bip39-mnemonic.py
Normal file → Executable file
0
how-to-create-encrypted-paper-backup/create-bip39-mnemonic.py
Normal file → Executable file
@ -1,16 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmBwlH8ACgkQH6dnhiu9
|
||||
EwWREg/+OmH/jkL8MpazXOVivugSF9p7mxAos2stMB/w1VTRoRWrIO5tLAwNVzcE
|
||||
FmqXiDE3mcuX/CdQamYKHdfuQ78hOGQFo+coTXyDeEhJzzB/ThDOsJw6d6JxV3xl
|
||||
tiT2OVdmo2HwOU8GZXXbsgWQArf7BwYU12YQe06JCOenfuo7ezrHmrAUjiBk2+AK
|
||||
RB4fhQ2wBiZQ4m2PjD6tJK9CCVNKWH2sSaP4jeZ2/7JHeykSKKpRUYglCVqP1gHP
|
||||
mF2Ii1Ox6lNCfkr822ZttuxX7NKO6mVnYlHSbFFOeW4VFl78CHqM529+BVNFOLCo
|
||||
LXi5TKl7HjGI9A3WAm1UkUdU5vmmAyvZSaON56bCk/6V3sZ1vbKkKL1TztxGm4l+
|
||||
M9GEtrDIFGcwtaFejxrQYvwC/KFHr96A3Cl4/qTCCrD8WsY1y9La07YTsgTj7zsB
|
||||
yQMbdou4Ixqh+pvXdhOujLnWuLLHVjveBPzJmIPT181GZ8vLMl8S+S63DAf+jPSz
|
||||
IQjLN0WNL717RE5J5DYOg4zpeO7v5GfUSCWANgXCJQZNKBJK4Bp/0mpHZ6keCBDQ
|
||||
Js34tKEV9DXkJHJV59WrdiW9JPIFtXsjSd6bbJBgsm7v7thO0EVCkBlOCel5oGPs
|
||||
Gj02RtcGJRQF8vK8kIciQF8jbYgVTuaMWI4ek4+gDsxsGGeBhhI=
|
||||
=i0UJ
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmB4b74ACgkQH6dnhiu9
|
||||
EwXhHw/+L8HtMoB+Fzh7WWVtXGw5q+oUHZUOFDe7WdOnFc0orbMhiKjtyEmQp11M
|
||||
ys9Lxni4pnQEiItyppT8qGxFyfvMDdbnYN5wyKJG4LL4sli0V8khKaug2FEDEuUV
|
||||
RPu2qxxNe+dOi7AJLn1yy+G6DztfTtkc/WI+KNS41ZjgV0jPt8DITLIKvr1DCNjJ
|
||||
L/MCaMxhnjjENRq3bYluu+z9C8Gq3clkwvKsG18XnYFh6Rv/YXfAWI7hA3fmGUjJ
|
||||
LewpwGN+ypIjzDfB11GdykZogd/0yM8KB8UV+yQFaNa6VaD8flUDP83WXJGGk37K
|
||||
+sRu/T1GLacI4T82ivOOV3u/+Wox7lXX37vok9eSES6u5oF9cFuTvoXgT2USp4OV
|
||||
74fL0uCU433FZgItvbUkgiThll8LL/vUy/Isx3yKoGp6D/VlvADgknDCG9OMXxG+
|
||||
GKLTbnBZBJVh0YF6Kf43Zx8ZoOFGa9TIvsGGXN1cSjcTZ7re24j1mpTSP0N0vMsc
|
||||
spoQSq1lO0YoVrr+9fOoG5kzWeFZlmca4D2NRFg/g+gv/qwjazm0zzCUQRA6A50G
|
||||
nSSeo2YskBSyEDYQfaqHBJB9qL+pObIrUdP0G7GkAdp5u/tAxnFdAqO+kWntI7f5
|
||||
cJz0I737arcOwzS/+sdYRblQiU4tyZ8W6SpAuTro0NS0CW26Nn8=
|
||||
=8fLc
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
set -e
|
||||
|
||||
number_of_shares=5
|
||||
share_threshold=3
|
||||
|
||||
positional=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
argument="$1"
|
||||
@ -14,6 +17,11 @@ while [[ $# -gt 0 ]]; do
|
||||
" --create-bip39-mnemonic create BIP39 mnemonic" \
|
||||
" --create-electrum-mnemonic create Electrum mnemonic" \
|
||||
" --validate-bip39-mnemonic validate if secret is valid BIP39 mnemonic" \
|
||||
" --shamir-secret-sharing split secret using Shamir Secret Sharing" \
|
||||
" --number-of-shares number of shares (defaults to 5)" \
|
||||
" --share-threshold shares required to access secret (defaults to 3)" \
|
||||
" --no-encryption disable symmetric encryption (shamir-only)" \
|
||||
" --no-qr disable “Show SHA512 hash as QR code”" \
|
||||
" --label <label> print label after short hash" \
|
||||
" -h, --help display help for command"
|
||||
exit 0
|
||||
@ -30,6 +38,28 @@ while [[ $# -gt 0 ]]; do
|
||||
validate_bip39_mnemonic=true
|
||||
shift
|
||||
;;
|
||||
--shamir-secret-sharing)
|
||||
shamir_secret_sharing=true
|
||||
shift
|
||||
;;
|
||||
--number-of-shares)
|
||||
number_of_shares=$2
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--share-threshold)
|
||||
share_threshold=$2
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--no-encryption)
|
||||
no_encryption=true
|
||||
shift
|
||||
;;
|
||||
--no-qr)
|
||||
no_qr=true
|
||||
shift
|
||||
;;
|
||||
--label)
|
||||
label=$2
|
||||
shift
|
||||
@ -56,17 +86,17 @@ usb="/tmp/usb"
|
||||
|
||||
tput reset
|
||||
|
||||
waitForUsbThumbDrive () {
|
||||
wait_for_usb_flash_drive () {
|
||||
if [ ! -e $dev ]; then
|
||||
printf "Insert USB flash drive and press enter"
|
||||
printf "$bold%s$normal" "Insert USB flash drive and press enter"
|
||||
read -r confirmation
|
||||
waitForUsbThumbDrive
|
||||
wait_for_usb_flash_drive
|
||||
fi
|
||||
}
|
||||
|
||||
waitForUsbThumbDrive
|
||||
wait_for_usb_flash_drive
|
||||
|
||||
printf "%s\n" "Format USB flash drive? (y or n)? "
|
||||
printf "$bold%s$normal\n" "Format USB flash drive? (y or n)? "
|
||||
|
||||
read -r answer
|
||||
if [ "$answer" = "y" ]; then
|
||||
@ -97,12 +127,14 @@ fi
|
||||
|
||||
if [ -z "$secret" ]; then
|
||||
tput sc
|
||||
printf "%s\n" "Type secret and press enter"
|
||||
read -r secret
|
||||
printf "$bold%s$normal\n" "Type secret and press enter, then ctrl-d"
|
||||
readarray -t secret_array
|
||||
secret=$(printf "%s\n" "${secret_array[@]}")
|
||||
tput rc
|
||||
tput ed
|
||||
printf "%s\n" "Type secret and press enter (again)"
|
||||
read -r secret_confirmation
|
||||
printf "$bold%s$normal\n" "Type secret and press enter, then ctrl-d (again)"
|
||||
readarray -t secret_confirmation_array
|
||||
secret_confirmation=$(printf "%s\n" "${secret_confirmation_array[@]}")
|
||||
if [ ! "$secret" = "$secret_confirmation" ]; then
|
||||
printf "$red%s$normal\n" "Secrets do not match"
|
||||
exit 1
|
||||
@ -111,43 +143,93 @@ fi
|
||||
|
||||
if [ "$validate_bip39_mnemonic" = true ]; then
|
||||
printf "%s\n" "Validating if secret is valid BIP39 mnemonic…"
|
||||
if ! echo -n $secret | python3 $basedir/validate-bip39-mnemonic.py; then
|
||||
printf "$red%s$normal\n" "Invalid BIP39 mnemonic"
|
||||
if ! echo -n "$secret" | python3 $basedir/validate-bip39-mnemonic.py; then
|
||||
printf "$bold$red%s$normal\n" "Invalid BIP39 mnemonic"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
encrypted_secret=$(echo -n "$secret" | gpg --s2k-mode 3 --s2k-count 65011712 --s2k-digest-algo sha512 --cipher-algo AES256 --symmetric --armor)
|
||||
gpg-connect-agent reloadagent /bye > /dev/null 2>&1
|
||||
|
||||
encrypted_secret_hash=$(echo -n "$encrypted_secret" | openssl dgst -sha512 | sed 's/^.* //')
|
||||
encrypted_secret_short_hash=$(echo -n "$encrypted_secret_hash" | head -c 8)
|
||||
|
||||
printf "%s\n" "$encrypted_secret"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 hash" "$encrypted_secret_hash"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 short hash" "$encrypted_secret_short_hash"
|
||||
|
||||
echo -n "$encrypted_secret" | qr --error-correction=H > "$tmp/secret.png"
|
||||
|
||||
font_size=$(echo "$(convert "$tmp/secret.png" -format "%h" info:) / 8" | bc)
|
||||
text_offset=$(echo "$font_size * 1.5" | bc)
|
||||
|
||||
if [ -z "$label" ]; then
|
||||
text="$encrypted_secret_short_hash"
|
||||
else
|
||||
text="$encrypted_secret_short_hash $label"
|
||||
if [ -z "$shamir_secret_sharing" ] || ([ "$shamir_secret_sharing" = true ] && [ -z "$no_encryption" ]); then
|
||||
encrypted_secret=$(echo -n "$secret" | gpg --s2k-mode 3 --s2k-count 65011712 --s2k-digest-algo sha512 --cipher-algo AES256 --symmetric --armor)
|
||||
gpg-connect-agent reloadagent /bye > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
convert "$tmp/secret.png" -gravity center -scale 200% -extent 125% -scale 125% -gravity south -font /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf -pointsize $font_size -fill black -draw "text 0,$text_offset '$text'" "$usb/$encrypted_secret_short_hash.jpg"
|
||||
if [ "$shamir_secret_sharing" = true ]; then
|
||||
if [ -n "$encrypted_secret" ]; then
|
||||
secret="$encrypted_secret"
|
||||
fi
|
||||
|
||||
printf "%s\n" "Show SHA512 hash as QR code? (y or n)? "
|
||||
share_number=1
|
||||
for share in $(echo -n "$secret" | secret-share-split -n $number_of_shares -t $share_threshold); do
|
||||
printf "$bold%s$normal\n" "Generating share $share_number or $number_of_shares…"
|
||||
|
||||
read -r answer
|
||||
if [ "$answer" = "y" ]; then
|
||||
printf "%s\n" "Press q to quit"
|
||||
sleep 1
|
||||
echo -n "$encrypted_secret_hash" | qr --error-correction=L > "$tmp/secret-hash.png"
|
||||
sudo fim --autozoom --quiet --vt 1 "$tmp/secret-hash.png"
|
||||
encrypted_secret="$share"
|
||||
encrypted_secret_hash=$(echo -n "$encrypted_secret" | openssl dgst -sha512 | sed 's/^.* //')
|
||||
encrypted_secret_short_hash=$(echo -n "$encrypted_secret_hash" | head -c 8)
|
||||
|
||||
printf "%s\n" "$encrypted_secret"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 hash" "$encrypted_secret_hash"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 short hash" "$encrypted_secret_short_hash"
|
||||
|
||||
echo -n "$encrypted_secret" | qr --error-correction L > "$tmp/secret.png"
|
||||
|
||||
font_size=$(echo "$(convert "$tmp/secret.png" -format "%h" info:) / 8" | bc)
|
||||
text_offset=$(echo "$font_size * 1.5" | bc)
|
||||
|
||||
if [ -z "$label" ]; then
|
||||
text="$encrypted_secret_short_hash $share_number"
|
||||
else
|
||||
text="$encrypted_secret_short_hash $label-$share_number"
|
||||
fi
|
||||
|
||||
convert "$tmp/secret.png" -gravity center -scale 200% -extent 125% -scale 125% -gravity south -font /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf -pointsize $font_size -fill black -draw "text 0,$text_offset '$text'" "$usb/$encrypted_secret_short_hash.jpg"
|
||||
|
||||
if [ -z "$no_qr" ]; then
|
||||
printf "$bold%s$normal\n" "Show SHA512 hash as QR code? (y or n)? "
|
||||
|
||||
read -r answer
|
||||
if [ "$answer" = "y" ]; then
|
||||
printf "$bold%s$normal\n" "Press q to quit"
|
||||
sleep 1
|
||||
echo -n "$encrypted_secret_hash" | qr --error-correction L > "$tmp/secret-hash.png"
|
||||
sudo fim --autozoom --quiet --vt 1 "$tmp/secret-hash.png"
|
||||
fi
|
||||
fi
|
||||
|
||||
share_number=$((share_number+1))
|
||||
done
|
||||
else
|
||||
encrypted_secret_hash=$(echo -n "$encrypted_secret" | openssl dgst -sha512 | sed 's/^.* //')
|
||||
encrypted_secret_short_hash=$(echo -n "$encrypted_secret_hash" | head -c 8)
|
||||
|
||||
printf "%s\n" "$encrypted_secret"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 hash" "$encrypted_secret_hash"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 short hash" "$encrypted_secret_short_hash"
|
||||
|
||||
echo -n "$encrypted_secret" | qr --error-correction L > "$tmp/secret.png"
|
||||
|
||||
font_size=$(echo "$(convert "$tmp/secret.png" -format "%h" info:) / 8" | bc)
|
||||
text_offset=$(echo "$font_size * 1.5" | bc)
|
||||
|
||||
if [ -z "$label" ]; then
|
||||
text="$encrypted_secret_short_hash"
|
||||
else
|
||||
text="$encrypted_secret_short_hash $label"
|
||||
fi
|
||||
|
||||
convert "$tmp/secret.png" -gravity center -scale 200% -extent 125% -scale 125% -gravity south -font /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf -pointsize $font_size -fill black -draw "text 0,$text_offset '$text'" "$usb/$encrypted_secret_short_hash.jpg"
|
||||
|
||||
if [ -z "$no_qr" ]; then
|
||||
printf "$bold%s$normal\n" "Show SHA512 hash as QR code? (y or n)? "
|
||||
|
||||
read -r answer
|
||||
if [ "$answer" = "y" ]; then
|
||||
printf "$bold%s$normal\n" "Press q to quit"
|
||||
sleep 1
|
||||
echo -n "$encrypted_secret_hash" | qr --error-correction L > "$tmp/secret-hash.png"
|
||||
sudo fim --autozoom --quiet --vt 1 "$tmp/secret-hash.png"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
sudo umount $usb
|
||||
|
@ -1,16 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmBwlEEACgkQH6dnhiu9
|
||||
EwVyThAAhOL3rmLVRKvfTlvabFGw1jUiyrcTmHThKOC1PIpDibNlwnR+Q78AiPnQ
|
||||
Gyh8AU62uHOkRRaqV7qNo3wCS4SsOlN5XNEHWm/VoZ70ogG80vIaBdVgdvnrvMMp
|
||||
zQC0gStyQ2Hjqz/5dDujl+u3Uiqr60b7lhvcILFB+Ado3L2hVN1UGiXOmZ9lAXzi
|
||||
9pPWihL4S0N3jAsAf0iHRM234/hoFr6hTycTGcnJxTu63KcUbESJh6pWQlXnEcJN
|
||||
vJzUk3IILkAmcQFhZCroJb9bCz2AztWaUYZn+acgp7LEU0QhmE1H8jdliDrjwYbh
|
||||
p/zUR99LLHf+H6Qu0mjNgy3lckX6mJpEu6S1wbjtjRsr2uU+h2SQmzmE64rV5Hzl
|
||||
T+iGECNReaFobT8Sq9Rp1j10vd+8/x7BW4QsxUTTgFOOIicWgN3gyyL2u6fci47a
|
||||
iO+md04jzb1U63YjYadX0HPtP8aI9v8uf+v0x+XyvKdIWjow/sqGJWuYJvOtXAiq
|
||||
EObChx6WjK2xWB8SkjQ4Y+pPHK+cnV+iG9nkuVnNyeIVNghhNlXIJaOwAARDBeNi
|
||||
5GEdfeCU7NncMWzz5yWD6hJUSngRC355EIg0hAam1fgYDp7GUOZ6RekFL2q0i0ke
|
||||
p3D/rTpu352dAY3Qbojm9FzH3nAuG0f+HmmKquG4o4o3TZJENI0=
|
||||
=gAGQ
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmB4b8oACgkQH6dnhiu9
|
||||
EwXU8hAAjniLPGQulMSmilV8/02BC0FWHHNzYS1m1KlvQ5IYCCUYwFttoVMv7/ME
|
||||
dLnGJdJ6I9bMQwa/AzjkgP5qKCY0PAiNKy3QrqFegyxyU1lWSPzHxCUg/1IdtCee
|
||||
95LKynPm+OuMJDespNPYCJgBlgIR5qrXSstUKL7vLFso8joUVig7W9aGkZ/Fw9ZW
|
||||
oXYnzod+KSuqGN3Zoplm2NzSxpAxjFJnSvM8f91Ht5CB1LgR3TdZNczMEe1r8+0D
|
||||
P/SAQYmD0HsvEFibcHeFQ4PO3x8plPWv+J8U6yK6dZdUhGKNCjdIDzLEpciLlMvZ
|
||||
9knBN0UhJ4kijVtFTDqqkiqjteeLr/ODrn1yV3EC179n5bzcDvXQTYy2MGMhUrU3
|
||||
uprrCZpjrfLXXG8PkTR7E2OEJnyiZADp2rYoJ6TiXFJI4oZz644N1X1N9euTnxyA
|
||||
BzZmpP3XR46t8gi0P66n0HCzumeopHTE5I20GISvNVfUFNUVOze1Cfm7SPtf3nNg
|
||||
CLqGcQtbcKotMsLnBs7w4wLV72f5K2VauVuwXsUkx7GT0xALUEC7846DF1NlZ5Dr
|
||||
fjTCjXgib3VDIh6wYLxEpKcNLuZqVxdh9k92aA3hHg7eHhJyzMp1S+iC38HaxKbb
|
||||
sbeAiqS1NH1MdznhJaSTwzMLIQGk1BRwmADHcAu8l52th9YLvYM=
|
||||
=MSRZ
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -26,9 +26,17 @@ set -- "${positional[@]}"
|
||||
tput reset
|
||||
|
||||
printf "%s\n" "Restoring…"
|
||||
. qr-restore.sh
|
||||
|
||||
printf "%s\n" "Type qr-restore.sh options and press enter (see “qr-restore.sh --help”)"
|
||||
read -r qr_restore_options
|
||||
|
||||
. qr-restore.sh $qr_restore_options
|
||||
|
||||
if [ -n "$secret" ]; then
|
||||
printf "%s\n" "Backing up…"
|
||||
. qr-backup.sh
|
||||
|
||||
printf "%s\n" "Type qr-backup.sh options and press enter (see “qr-backup.sh --help”)"
|
||||
read -r qr_backup_options
|
||||
|
||||
. qr-backup.sh $qr_backup_options
|
||||
fi
|
||||
|
@ -1,16 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmBwlE4ACgkQH6dnhiu9
|
||||
EwU2VxAAmyz3lZPBFIz8PbZBTZD0OofU3cs/5gC3NX+isaBi/rKqCAmaI2mgPbM8
|
||||
d4IKMNI/wHXa+ph1N7THJWE2tM1G2VZBQsFsT9hAWYpJgpB0nJtNdnq8W7d0/BrL
|
||||
3/vJC/uD4mOG5Bm53bsmHOFH/r37J/mF/IgIhSnMA3C+sMuqph/OIGhHus28Qz0O
|
||||
pIYDQVu2pb8SIUAEHB1Ui4fdVRn8Z9wJY6/+pOFH2FseD65gE/XEqt9F9ooC7puw
|
||||
17ALoVeu24TncTjIlIvWeQVEHh2BQfNkHLP0Oz4fY6if1u+bQvUgbakNlMNQtN44
|
||||
semaWd7jYgtNCcr/H9MZZXEyQzdI7sGFpQ6AFcFk+hlt2CW1WTKPv8J9F28s4QDn
|
||||
0K3golSbzDnZxBphKsLiwL8d3SLCMURDUt00aPvgnphlDOaV5rvOlS6Uu6YNqysx
|
||||
AS0FGtW/qhmZ8oLqHI49dtUyqoRpB2XGAOiAp25Jsh38MSdEi9bJGj5n3Do0ZnFk
|
||||
VAovLOTp4l5xF1Z1pLFH7ZUHkOUtFTTd8LIUWOqol6kxloShAsZ8UXMchN6XQX5j
|
||||
oQsPFGvgDAnGt2iXX4Wzj+61s3e6afvpg6SH2hp1MLrziDWTXikokYMMnFeZhOz0
|
||||
QpPO3KutjsMRdRm2wPF3R5tQDWOXxbvoVONAOQc1sEPGmLgH+8w=
|
||||
=8nFo
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmB4b80ACgkQH6dnhiu9
|
||||
EwV4oA//WxF7IbBueNKVZgRa/oGBRMzHKwDUTPg6HIScS+MqJ3oyKJDpWJ/UhsE5
|
||||
XB06yR1GEwP9bTHFBCHiGNOYJHml0wS4dhlUtWFWnfGBFIOm07/LbBcHH9uTCIno
|
||||
YVv8dhrGRwamxJh/AyfU7MCjJcsgaVniakJsX7L/OgPJymuH4ympNNjvH2Dy0AzV
|
||||
mLJ4380zMEs09/aCIFnSEOxzjqjwJmtQF9ZZKiJs+rYP7PkuNmJGBSPWCF2ErJCY
|
||||
NaQVfUrco7zFepjMNn3GSNUyBoU31wlUf/blmPHynYJ/NJR3R84x78J7K8S39ShW
|
||||
1/xlf6dkto9pYVU4NMq0bt7PVgOImKK9FORZG3kJJu1l57RmiZ5lVcmVkrEi+6LY
|
||||
8wnLr7aYfXkwas+wzE/IBc7b5Zms4bjyv7dFkf3uCZwgyIqHdOOc4/ErUfGUyKVG
|
||||
eCh+LqUEUzpDDDjVAC+jFOR8Mi2ES+AjAgbb0URDAqO1owILQdiTmo0oMHrQ+x47
|
||||
G6GqEAuaETOkk3+CgX6E7B7gn3AYVyX6IMP9h6ESsGWoS+TVrYeSqrxaprgnqjCd
|
||||
tMxvr0zAGVInyPjKg3XDxEQjkDq9BWwEPLElq9pk6jaYrgwQchonKQUFBSP5oiQs
|
||||
sENAaTQhI8LyQDdPPyNckT7uyzc7VfUtROn5qZsFqawKxvBBrdU=
|
||||
=qPkK
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
share_threshold=3
|
||||
|
||||
positional=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
argument="$1"
|
||||
@ -11,10 +13,21 @@ while [[ $# -gt 0 ]]; do
|
||||
"Usage: qr-restore.sh [options]" \
|
||||
"" \
|
||||
"Options:" \
|
||||
" --word-list split secret into word list" \
|
||||
" -h, --help display help for command"
|
||||
" --shamir-secret-sharing combine secret using Shamir Secret Sharing" \
|
||||
" --share-threshold shares required to access secret (defaults to 3)" \
|
||||
" --word-list split secret into word list" \
|
||||
" -h, --help display help for command"
|
||||
exit 0
|
||||
;;
|
||||
--shamir-secret-sharing)
|
||||
shamir_secret_sharing=true
|
||||
shift
|
||||
;;
|
||||
--share-threshold)
|
||||
share_threshold=$2
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--word-list)
|
||||
word_list=true
|
||||
shift
|
||||
@ -34,39 +47,45 @@ normal=$(tput sgr0)
|
||||
|
||||
tput reset
|
||||
|
||||
printf "%s\n" "Scan QR code…"
|
||||
scan_qr_code () {
|
||||
local -n data=$1
|
||||
|
||||
data=""
|
||||
printf "%s\n" "Scanning QR code…"
|
||||
|
||||
data=$(zbarcam --nodisplay --oneshot --quiet --set disable --set qrcode.enable | sed 's/QR-Code://')
|
||||
|
||||
while read line; do
|
||||
if echo -n $line | grep -Eq "^QR-Code:"; then
|
||||
line=$(echo -n $line | sed 's/QR-Code://')
|
||||
fi
|
||||
data="$data$line"
|
||||
if [ "$line" = "-----END PGP MESSAGE-----" ]; then
|
||||
killall zbarcam --signal SIGINT
|
||||
else
|
||||
data="$data\n"
|
||||
fi
|
||||
done < <(zbarcam --nodisplay --quiet)
|
||||
data_hash=$(echo -n "$data" | openssl dgst -sha512 | sed 's/^.* //')
|
||||
data_short_hash=$(echo -n "$data_hash" | head -c 8)
|
||||
|
||||
encrypted_secret=$(echo -e $data)
|
||||
printf "%s\n" "$data"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 hash" "$data_hash"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 short hash" "$data_short_hash"
|
||||
}
|
||||
|
||||
encrypted_secret_hash=$(echo -n "$encrypted_secret" | openssl dgst -sha512 | sed 's/^.* //')
|
||||
encrypted_secret_short_hash=$(echo -n "$encrypted_secret_hash" | head -c 8)
|
||||
|
||||
printf "%s\n" "$encrypted_secret"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 hash" "$encrypted_secret_hash"
|
||||
printf "%s: $bold%s$normal\n" "SHA512 short hash" "$encrypted_secret_short_hash"
|
||||
if [ "$shamir_secret_sharing" = true ]; then
|
||||
for share_number in $(seq 1 $share_threshold); do
|
||||
printf "$bold%s$normal" "Prepare share $share_number or $share_threshold and press enter"
|
||||
read -r confirmation
|
||||
scan_qr_code share
|
||||
shares="$share\n$shares"
|
||||
done
|
||||
encrypted_secret="$(echo -e "$shares" | secret-share-combine)"
|
||||
else
|
||||
scan_qr_code encrypted_secret
|
||||
fi
|
||||
|
||||
printf "$bold$red%s$normal\n" "Show secret? (y or n)? "
|
||||
|
||||
read -r answer
|
||||
if [ "$answer" = "y" ]; then
|
||||
secret=$(echo -e "$encrypted_secret" | gpg --decrypt)
|
||||
gpg-connect-agent reloadagent /bye > /dev/null 2>&1
|
||||
if [[ "$encrypted_secret" =~ "-----BEGIN PGP MESSAGE-----" ]]; then
|
||||
secret=$(echo -e "$encrypted_secret" | gpg --decrypt)
|
||||
else
|
||||
secret=$encrypted_secret
|
||||
fi
|
||||
|
||||
if [ "$word_list" = true ]; then
|
||||
printf "%s" "Secret: "
|
||||
printf "%s\n" "Secret:"
|
||||
array=($secret)
|
||||
last_index=$(echo "${#array[@]} - 1" | bc)
|
||||
for index in ${!array[@]}; do
|
||||
@ -78,7 +97,8 @@ if [ "$answer" = "y" ]; then
|
||||
done
|
||||
printf "\n"
|
||||
else
|
||||
printf "Secret: $bold%s$normal\n" "$secret"
|
||||
printf "%s\n" "Secret:"
|
||||
echo "$bold$secret$normal"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmBwlGIACgkQH6dnhiu9
|
||||
EwXmIRAAkvOeg6JdP77p0PqtxPji4NkFed3IqMPQ2Ds4jNyJi04y47xDXtEonopB
|
||||
24GpfEwsiWUa0+JQ8+2w64le72HVBvsEueUpTHEGW0Z9a/n2dHf7eXqIq+U8N0eH
|
||||
enGLawf2DnHOtyEUV1g9eFkiyvKhq6QdVZfggIiRpJTqpuK2zk+jS+K1ESa1GTGM
|
||||
1w3ItrU80aflrSB9my2rKA46++Buhf1WN13Z7BQ5xrSX+NQQzmEnwnQfcc1bLkWK
|
||||
vvojpCs3L7cZC8mEiIIDYMDolvefuZN7/rr7lzbR2wazYdRHv31HGYKHAAFxdVTN
|
||||
a6CrQYsF4/xuDxOBsZZZ8nosaWywz7NVMLCDVRidaxkNgJ5reof1Hl6OA1oZEa6p
|
||||
PYiqzG8SRdHXaBAFXB+qkWubrStpgxJb6uIE5ye1p60fUKqCDFAMSKiMcvLk8ACG
|
||||
f3B7AqLsLtZC5Q4BMwQGruwUZ3aZlowGmHbS7kMLnU48l9i3/WcG4fccxU2TniQF
|
||||
ViQh3eMV/wrO7lsrA2coY6adCUKTb0a80EZ7hjA9T4T1VPcE1GCpWnl2p3gdvuCn
|
||||
0t3CMnTy4KkLvHW//7sZAoRazl+Fi+5n3+8eEiLjLhX5faXvwfT7JiT9/hcAWI6R
|
||||
gzjNauTZzARn/W7rcIrsMXMm+3tsVOqER4hxwsECuo9nj9T+/ac=
|
||||
=QC/S
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmB4b9AACgkQH6dnhiu9
|
||||
EwWL5w//ae+DA9VEF1pg/uQONGVDretYRo1rzJUFPT22U/ZmyOQHKG+SXGEfYizy
|
||||
LroEE9M98rqZHVDxA6WRZKFPQs/aNRggE6Qk8T3krzz/oebOenXV1N1Z7ZQH2gxj
|
||||
YJjaqM0Fw9UCRgPThfUdEpS652vyVjfAAwbwHkI+6flMDGV+TdM+5Fuy3XXXEhiG
|
||||
Yk4+rsGeRMf6MBFGqNI9urE9iSnRvw7S4joJNmazq9z6Adr/v2OFWHuWURFnUKzy
|
||||
rvE0frvGeAPzgxR/fnb5Tg4+1HR8p9UYTBo3/Krrv6mSMWrmsKdwADf2TO2hzC1b
|
||||
pGz7bjeZaYOyeJq8BB7ak/idn7DBk9DsbAs06HI3FyxIQcHZcW9XTihl5e7k7w+O
|
||||
NbPDNI20PgKCT7CII6U3Rs6LLyHCwsdyxmws70y3wmOQGSYE5bUtAFvCXn0jFpf2
|
||||
Aj82NsKanbhsgD15zokbrFwNFHNggQzxMSgRDwMhzbzhslCH580EkEynwR7KR0H1
|
||||
KR6ZAlL0vvXiTQ+QzWRwVjhRTpSps+yprX3ARTqehzgfTu8LXEUY0XLxtCpI9DFj
|
||||
zUBZkIpKKIWq7kaV85QyOMTFBW4oQJzo6jCo75HCznmPjKNQpmW9KMpTGR7PzmLb
|
||||
6/jJkW5wsw2AT24sytJ73R9Nsfp1UxzXM+o3nGHWFc/orn4OQhU=
|
||||
=VApF
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -34,6 +34,7 @@ done
|
||||
|
||||
set -- "${positional[@]}"
|
||||
|
||||
bold=$(tput bold)
|
||||
red=$(tput setaf 1)
|
||||
normal=$(tput sgr0)
|
||||
|
||||
@ -43,7 +44,7 @@ tput reset
|
||||
|
||||
waitForUsbThumbDrive () {
|
||||
if [ ! -e $dev ]; then
|
||||
printf "Insert USB flash drive and press enter"
|
||||
"$bold%s$normal" "Insert USB flash drive and press enter"
|
||||
read -r confirmation
|
||||
waitForUsbThumbDrive
|
||||
fi
|
||||
@ -51,7 +52,7 @@ waitForUsbThumbDrive () {
|
||||
|
||||
waitForUsbThumbDrive
|
||||
|
||||
printf "$red%s$normal\n" "Secure erase USB flash drive? (y or n)? "
|
||||
printf "$bold$red%s$normal\n" "Secure erase USB flash drive? (y or n)? "
|
||||
|
||||
read -r answer
|
||||
if [ "$answer" = "y" ]; then
|
||||
|
@ -1,16 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmBwlG4ACgkQH6dnhiu9
|
||||
EwVFHw//arziCrzzNMrP/OdYbhWGmLcoF18g3GnuPnatXbnukBwzi2llzMTPb93H
|
||||
D/P8ZaarUSyPOwgv29VdGjQQtr1FFbZ/7LCC+QJM9YFc26YJtI9DKqM/zkVnJLbl
|
||||
Q0zVjCvVNjeyxtDcyxs5gydce5uA3u5pyVaU6zYgP+ubi6GHScThGOb7HP5ObhJG
|
||||
Zc5Amkyp02RQg/BEhITZVaolkERtNoWE/UvKKTIsqNFNPMeFfsK8qB2aWswPYI6X
|
||||
GehGUN9HNIuLHWycw/uAaBtFrDjMqMtKR39aoNddW72TIyK/PBCF8/FVogbcBL6j
|
||||
eWVkhwUMkHWU5clhI627snASAWGa1OsELviArbfpzWYjX7Q9NbSlBGAALn1/u99C
|
||||
AjObM34aTG3XSRe/AFCt3EF6ok901wPpCnGE1fllk9kzNKOMu8WOhO9d53gSX4zz
|
||||
EMSr9kMA5M0pBtFONsZekVhTGM2LxLZ10uLvCY6f/KCfzvzjeODsqICE8eeNFVqZ
|
||||
h0YMlrPCvh6rsiZb6JiPGiXtcOMozl9DOs5kfRFoXi9RiJmhWISkdWme+eWuW0VS
|
||||
WymBbrTTRuMx9LODhT+RGYe4AvEiQP5eVpGoQbfX0qzr8HGn51wSYmI16YF/LYxS
|
||||
W7VfuLmbbkoHqMIrYuELlECA6By2XYI2o/eBiqOrS6SZrqtB3lM=
|
||||
=vj1f
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmB4b9IACgkQH6dnhiu9
|
||||
EwUzFhAAnz+mC1SKOS24bgPqtD2a22T0NmQ3N1SHRL9JIu79TvIUHkpAy8HN/ctH
|
||||
+DY7+A4266vf6HU79gnwbn2D2l75KqIn/O+J3LEGk4JUWgQTMbB6MMrZeGHKy0gX
|
||||
evVkdrADpdi158TVD2YzzclOU3SBbU1FCK6SiIq1mB7k0Ryd+rbHcX6ChBvmMAtS
|
||||
5OmpHok+NkpQ/oSLb6sqnd/EXf4s+6HmKHfbmnhGMr3TyXeSS8Vt3RzxEfFD/WfY
|
||||
9BGfZkdY70V+gxVWk06gFjS7491EVO+z7YrETrvYVmy88qUdPhJOW4kgf3L1xxN4
|
||||
aCyeduhJPpZfgAZ2PAn4jzOpZDbQZOGu9koWjII5hY0VEK0V+N4TTr2gHwMcA8Qp
|
||||
Gcrbp5sri5rHoqo1fXRw+C/1F++lprVe890Qhr6viE4YeU2AIL7AuB8+SJi/Xk9w
|
||||
lZvwZ6ckJ/xd76BASXwG5aOU3cHdb+0MFDDwtG4Rpf1LDq171OttNspaWa76nVur
|
||||
s5vB4oX8PUbtMraqbdBMAFoq94cBeeT9mO2Cb/JfxcanmH04Jw8gO0xI90ofX5Dx
|
||||
9tuMVR97HHSK3yl1ddMRFLuyO1+yofOh8XYH0abTNeerH5M/IItPZpZRMyGfU3W4
|
||||
4huhGfX8XYYpKKhuaMmE0ZHPHMRRKJqcwlqdJxk87UK68JSUbkQ=
|
||||
=BBuj
|
||||
-----END PGP SIGNATURE-----
|
||||
|
0
how-to-create-encrypted-paper-backup/validate-bip39-mnemonic.py
Normal file → Executable file
0
how-to-create-encrypted-paper-backup/validate-bip39-mnemonic.py
Normal file → Executable file
@ -1,16 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmBwlIwACgkQH6dnhiu9
|
||||
EwVbrw//Tfteto+Qs0AmTqRxCoFmtU+NODNEqa9gWZNOJgQ76kk9c8AIuzq5WisW
|
||||
DbtLkraWJ+ajIoqOujNzc0u/EGraE4WtDQxG5XUUar6NiPhFIiy3C8oMo7tptI05
|
||||
hziIPVZU349Gh7zxC2UF3itwmQFJVrOe3DZ6+J0FUbVISBrNcC7siPAABFfSxGq6
|
||||
06JW6+M1U+nq0I/uTJ2/3G/iIUgd/zqnGNAFjMcgR5BnE957i93ztkoCkduNxw42
|
||||
Jg/c781sOEoJOCTJTWRjMg7WbmjOiTnyVfd7pP5XbGUz1ClwIC0rQ+LDfkQjKlh9
|
||||
ie9f1t8tUAPOK3wlRQ5wddJLiry5LHoSBx4oY0LUhPKgKyzNdKfpWKaU7sjOzgn8
|
||||
RbWnvJBblLKCmvFc2V2WmimiZNHg1Pc3lVX1r+cMP/UgaFu8yZhD/RwrpHPu/Vsd
|
||||
0GfYAJoT0nhSvmdz5dYN/HDQ2cs/Aj/rmcTpDDdv+OU9GL02VsQPkHnDtSVLtlxP
|
||||
PNjs4CO721VXDhc8EiWYpQ+hc3xrwO/FO5Hv2i5kCWX5rieLA4L99CvisZLz2z/o
|
||||
OldeSXK16G/VIlmsNyJ3d4V3xdgheHM7DDwcPODBgBiYJ19RL5nyd71XUq7fYhRQ
|
||||
mJvEAkEM/mQf/4H5gTHYOEO4Bz5ipP1YCZjeysxLGDNfcyqYmq8=
|
||||
=9kI6
|
||||
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmB4b8IACgkQH6dnhiu9
|
||||
EwW89xAAg9D7Sv99IRD8gV9z8Jn9zirPE4uJIs4PQardKDniIqmHjz2MFNXTdzAW
|
||||
C7VKLM8LBkM4E2UXhBfQSfnbG8i4CAIZfOP2vvEMFuBS5C/O+PmWuwCM+REIg1K6
|
||||
Urn29l55ljgZ9l0o0URkCx4jGtvtTiHEP1UhiuRnA1f2IO0AMT4fEhSNCoo9IAwT
|
||||
lcd+5qH1sRiHTR9JdiUVkAzw6qhB7tsHR2qyhQnZQQ8F8sJiqBC176AmZHK2L86A
|
||||
T3BrK1TNrJtfRxocx3qrUwDJVp38LNFoMOFUKxKht6KCaVz7C6q7yaJnBkRRxm5r
|
||||
skIS8LzkWa6Yr5wm7M0kvckW8pElQ3EjFYuJaNyLvVxNPCDLZo39Em7oxTWZ6HqP
|
||||
y7ukVfcy5MbD/tqH2tWS/L89FULRwUkn8BK8HdYFBJgr8o/HTMzntpPF7hSJwMbH
|
||||
FH6CwFUOGxe5pIVpFb2FnBpMQeO8yrIGtbzWm76Jf5EFqyxBHJaVv+H60QU4BsEW
|
||||
rxjeFcMqJk9IjK9r0nIJ91YP0+8g6YRATD5nXbITh06c9oHSTspkHjOUkrlG8SCQ
|
||||
AaAGG8uXKKHLpV1PBHPqDCk2lTBkT0TrddhnEBbLDxvxfXOSharapC4jMv+smM2b
|
||||
lVJr+M8W+VDZ0iqk0+bYMNq9ymJOFkXwwMsvsGF3eJANU8yi2fk=
|
||||
=blqh
|
||||
-----END PGP SIGNATURE-----
|
||||
|
Loading…
x
Reference in New Issue
Block a user