Komutlarını kullanmak için cihazınıza GPG/PGP kurmak istemiyorsanız aşağıdaki Docker kurulumunu deneyebilirsiniz. Mevcut kurulumla mesajları şifreleyebilir ve şifrelerini çözebilirsiniz. Eklenebilecek tek şey, dosya şifreleme ve şifre çözmedir.


Gönderici veya alıcı olsanız dahi, make komutları için parolanızı girmeniz istenecektir. Her kullanıcının (test) kişisel ayrıntıları, örnek değerler kullanılarak .env.dist içinde tutulur. Gerçek kullanıcılar için bu dosya .env olarak çoğaltılmalı ve gerçek değerler içermelidir. Bu dosya ile birlikte /users/ klasörü, VCS taahhütlerinin dışında tutulur!


Yapı


Bu orijinal halidir.


├── .dockerignore
├── .env.dist
├── .gitignore
├── Dockerfile
├── Makefile
├── Readme.md
├── docker-compose.yaml
├── gpg.cfg
├── gpg.sh
└── users
├── ali
│   └── msg-to-encrypt.txt
└── bob
└── msg-to-encrypt.txt

Ali/bob'u gönderici/alıcı olarak kullandıktan ve aşağıdaki komutları çalıştırdıktan sonra elde edeceğiniz şey budur.


├── .dockerignore
├── .env.dist
├── .gitignore
├── Dockerfile
├── Makefile
├── Readme.md
├── docker-compose.yaml
├── gpg.cfg
├── gpg.sh
└── users
├── ali
│   ├── decrypted-msg.txt
│   ├── encrypted-msg.txt
│   ├── msg-to-decrypt.txt
│   ├── msg-to-encrypt.txt
│   ├── private.key
│   ├── public.key
│   └── trust.db
└── bob
├── decrypted-msg.txt
├── encrypted-msg.txt
├── msg-to-decrypt.txt
├── msg-to-encrypt.txt
├── private.key
├── public.key
└── trust.db

Dosyalar


ali/msg-to-encrypt.txt


Hello from Ali!

bob/msg-to-encrypt.txt


Hello from Bob!

.dockerignore


*
!/gpg.sh
!/gpg.cfg

.env.dist


ALI_NAME_REAL=Ali
ALI_NAME_COMMENT=Ali's account
ALI_NAME_EMAIL=ali@example.com
ALI_PASSPHASE=ali

BOB_NAME_REAL=Bob
BOB_NAME_COMMENT=Bob's account
BOB_NAME_EMAIL=bob@example.com
BOB_PASSPHASE=bob

.gitignore


users/*
!users/*/msg-to-encrypt.txt
.env

docker-compose.yaml


services:
gpg:
container_name: gpg
build:
context: "."
env_file:
- ".env"
environment:
- ACTION=${ACTION}
- USER=${USER}
- SENDER=${SENDER}
- RECEIVER=${RECEIVER}
volumes:
- "./users:/users"

Dockerfile


FROM alpine:3.16.0
COPY . .
RUN apk update && apk fetch gnupg && apk add gnupg && chmod +x gpg.sh
ENTRYPOINT ["./gpg.sh"]

gig.cfg


Key-Type: RSA
Key-Length: 2048
Subkey-Type: RSA
Subkey-Length: 2048
Name-Real: ${NAME_REAL}
Name-Comment: ${NAME_COMMENT}
Name-Email: ${NAME_EMAIL}
Expire-Date: 0
Passphrase: ${PASSPHASE}

gpg.sh


#!/bin/sh

set -eu

CYAN="\033[0;36m"
CLEAR="\033[0m"
GPG_DIR="/root/.gnupg"
USERS_DIR="/users"
PUBLIC_KEY_NAME="public.key"
PRIVATE_KEY_NAME="private.key"
TRUST_DB_NAME="trust.db"
DECRYPTED_MSG_NAME="decrypted-msg.txt"
ENCRYPTED_MSG_NAME="encrypted-msg.txt"
MESSAGE_TO_DECRYPT_NAME="msg-to-decrypt.txt"
MESSAGE_TO_ENCRYPT_NAME="msg-to-encrypt.txt"

gen_key() {
printf "${CYAN}> GENERATE USER's PUBLIC and PRIVATE KEYS (begin) ----------------------------------------${CLEAR}\n"

printf "${CYAN}Set local variables${CLEAR}\n"
USER_NAME_REAL="$(echo ${USER} | tr 'a-z' 'A-Z')_NAME_REAL"
USER_NAME_COMMENT="$(echo ${USER} | tr 'a-z' 'A-Z')_NAME_COMMENT"
USER_NAME_EMAIL="$(echo ${USER} | tr 'a-z' 'A-Z')_NAME_EMAIL"
USER_PASSPHASE="$(echo ${USER} | tr 'a-z' 'A-Z')_PASSPHASE"
USER_PUB_KEY="${USERS_DIR}/${USER}/${PUBLIC_KEY_NAME}"
USER_PRV_KEY="${USERS_DIR}/${USER}/${PRIVATE_KEY_NAME}"
USER_TRUST_DB="${USERS_DIR}/${USER}/${TRUST_DB_NAME}"
CONFIG_KEY="/gpg.cfg"
echo "done"

printf "${CYAN}Prepare configuration file${CLEAR}\n"
sed -i \
-e 's/${NAME_REAL}/'"$(printenv -- ${USER_NAME_REAL})"'/g' \
-e 's/${NAME_COMMENT}/'"$(printenv -- ${USER_NAME_COMMENT})"'/g' \
-e 's/${NAME_EMAIL}/'"$(printenv -- ${USER_NAME_EMAIL})"'/g' \
-e 's/${PASSPHASE}/'"$(printenv -- ${USER_PASSPHASE})"'/g' \
${CONFIG_KEY}
echo "done"

printf "${CYAN}Create gpg directory and get into it${CLEAR}\n"
gpg2 --list-keys
cd ${GPG_DIR}

printf "${CYAN}Generate keys${CLEAR}\n"
gpg2 --verbose --batch --gen-key ${CONFIG_KEY}

printf "${CYAN}Backup public and private keys${CLEAR}\n"
gpg2 --yes --output ${USER_PUB_KEY} --armor --export-options export-backup --export $(printenv -- ${USER_NAME_EMAIL})
gpg2 --yes --output ${USER_PRV_KEY} --armor --export-options export-backup --export-secret-keys $(printenv -- ${USER_NAME_EMAIL})
echo "done"

printf "${CYAN}Backup trust database${CLEAR}\n"
gpg2 --export-ownertrust > ${USER_TRUST_DB}
echo "done"

printf "${CYAN}Cleanup${CLEAR}\n"
cleanup
echo "done"

printf "${CYAN}> GENERATE USER's PUBLIC and PRIVATE KEYS (end) ------------------------------------------${CLEAR}\n"
}

enc_msg() {
printf "${CYAN}> SENDER ENCRYPTS a PLAIN MESSAGE for RECEIVER to DECRYPT (begin) ------------------------${CLEAR}\n"

printf "${CYAN}Set local variables${CLEAR}\n"
SENDER_PUB_KEY="${USERS_DIR}/${SENDER}/${PUBLIC_KEY_NAME}"
SENDER_PRV_KEY="${USERS_DIR}/${SENDER}/${PRIVATE_KEY_NAME}"
SENDER_TRUST_DB="${USERS_DIR}/${SENDER}/${TRUST_DB_NAME}"
SENDER_MSG_TO_ENCRYPT="${USERS_DIR}/${SENDER}/${MESSAGE_TO_ENCRYPT_NAME}"
SENDER_ENCRYPTED_MSG="${USERS_DIR}/${SENDER}/${ENCRYPTED_MSG_NAME}"
RECEIVER_PUB_KEY="${USERS_DIR}/${RECEIVER}/${PUBLIC_KEY_NAME}"
RECEIVER_EMAIL="$(echo ${RECEIVER} | tr 'a-z' 'A-Z')_NAME_EMAIL"
echo "done"

printf "${CYAN}Create gpg directory and get into it${CLEAR}\n"
gpg2 --list-keys
cd ${GPG_DIR}

printf "${CYAN}Restore sender's public key${CLEAR}\n"
gpg2 --import-options import-restore --import ${SENDER_PUB_KEY}

printf "${CYAN}Restore sender's private key${CLEAR}\n"
gpg2 --import-options import-restore --import ${SENDER_PRV_KEY}

printf "${CYAN}Restore sender's trust database${CLEAR}\n"
rm trustdb.gpg
gpg2 --import-ownertrust < ${SENDER_TRUST_DB}

printf "${CYAN}Restore receiver's public key${CLEAR}\n"
gpg2 --import-options import-restore --import ${RECEIVER_PUB_KEY}

printf "${CYAN}Verify receiver's public key${CLEAR}\n"
gpg2 --fingerprint $(printenv -- ${RECEIVER_EMAIL})

printf "${CYAN}Sign receiver's public key${CLEAR}\n"
gpg2 --sign-key $(printenv -- ${RECEIVER_EMAIL})

printf "${CYAN}Sender encrypts message for receiver${CLEAR}\n"
gpg2 --batch --yes --output ${SENDER_ENCRYPTED_MSG} --encrypt --sign --armor -r $(printenv -- ${RECEIVER_EMAIL}) ${SENDER_MSG_TO_ENCRYPT}
echo "done"

printf "${CYAN}Cleanup${CLEAR}\n"
cleanup
echo "done"

printf "${CYAN}> SENDER ENCRYPTS a PLAIN MESSAGE for RECEIVER to DECRYPT (end) --------------------------${CLEAR}\n"
}

dec_msg() {
printf "${CYAN}> RECEIVER DECRYPTS SENDER's ENCRYPTED MESSAGE (begin) -----------------------------------${CLEAR}\n"

printf "${CYAN}Set local variables${CLEAR}\n"
RECEIVER_PUB_KEY="${USERS_DIR}/${RECEIVER}/${PUBLIC_KEY_NAME}"
RECEIVER_PRV_KEY="${USERS_DIR}/${RECEIVER}/${PRIVATE_KEY_NAME}"
RECEIVER_TRUST_DB="${USERS_DIR}/${RECEIVER}/${TRUST_DB_NAME}"
SENDER_PUB_KEY="${USERS_DIR}/${SENDER}/${PUBLIC_KEY_NAME}"
SENDER_EMAIL="$(echo ${SENDER} | tr 'a-z' 'A-Z')_NAME_EMAIL"
RECEIVER_MSG_TO_DECYPT="${USERS_DIR}/${RECEIVER}/${MESSAGE_TO_DECRYPT_NAME}"
RECEIVER_DECRYPTED_MSG="${USERS_DIR}/${RECEIVER}/${DECRYPTED_MSG_NAME}"
echo "done"

printf "${CYAN}Create gpg directory and get into it${CLEAR}\n"
gpg2 --list-keys
cd ${GPG_DIR}

printf "${CYAN}Restore receiver's public key${CLEAR}\n"
gpg2 --import-options import-restore --import ${RECEIVER_PUB_KEY}

printf "${CYAN}Restore receiver's private key${CLEAR}\n"
gpg2 --import-options import-restore --import ${RECEIVER_PRV_KEY}

printf "${CYAN}Restore receiver's trust database${CLEAR}\n"
rm trustdb.gpg
gpg2 --import-ownertrust < ${RECEIVER_TRUST_DB}

printf "${CYAN}Restore sender's public key${CLEAR}\n"
gpg2 --import-options import-restore --import ${SENDER_PUB_KEY}

printf "${CYAN}Verify sender's public key${CLEAR}\n"
gpg2 --fingerprint $(printenv -- ${SENDER_EMAIL})

printf "${CYAN}Sign sender's public key${CLEAR}\n"
gpg2 --sign-key $(printenv -- ${SENDER_EMAIL})

printf "${CYAN}Receiver decrypts sender's encrypted message${CLEAR}\n"
gpg2 --decrypt ${RECEIVER_MSG_TO_DECYPT} > ${RECEIVER_DECRYPTED_MSG}

printf "${CYAN}Cleanup${CLEAR}\n"
cleanup
echo "done"

printf "${CYAN}> RECEIVER DECRYPTS SENDER's ENCRYPTED MESSAGE (end) -------------------------------------${CLEAR}\n"
}

cleanup() {
cd /
rm -rf ${GPG_DIR}
rm gpg.sh gpg.cfg
}

if [ ${ACTION} == "gen-key" ]; then gen_key; fi
if [ ${ACTION} == "enc-msg" ]; then enc_msg; fi
if [ ${ACTION} == "dec-msg" ]; then dec_msg; fi

Makefile


.PHONY: help
help: ## Display available commands.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

.PHONY: gen-key
gen-key: ## Generate public and private keys for a user. Usage: `make gen-key USER=ali`
make down
ACTION=gen-key USER=${USER} docker-compose run --rm gpg

.PHONY: enc-msg
enc-msg: ## Sender encrypts plain message for receiver to decrypt. Usage: `make enc-msg SENDER=ali RECEIVER=bob`
make down
ACTION=enc-msg SENDER=${SENDER} RECEIVER=${RECEIVER} docker-compose run --rm gpg

.PHONY: dec-msg
dec-msg: ## Receiver decrypts sender's encrypted message. `make dec-msg SENDER=ali RECEIVER=bob`
make down
ACTION=dec-msg SENDER=${SENDER} RECEIVER=${RECEIVER} docker-compose run --rm gpg

.PHONY: config
config: ## Dump docker-compose configuration.
docker-compose config

.PHONY: down
down: ## Clean up docker artefacts.
docker-compose down
@-docker rmi gpg_gpg
docker system prune --volumes --force

Komutlar


Anahtar oluşturma


Genel ve özel anahtarlar oluşturur ve ardından bunları "güven" veritabanı dahil olmak üzere /users/{name}/ klasörüne yedekler. Oluşturulan dosyalar private.key, public.key ve trust.db şeklindedir. public.key daha sonra mesajların şifresini çözmek için üçüncü taraflarla paylaşılabilir.


$ make gen-key USER=Ali

> GENERATE USERs PUBLIC and PRIVATE KEYS (begin) ----------------------------------------
Set local variables
done
Prepare configuration file
done
Create gpg directory and get into it
gpg: directory /root/.gnupg created
gpg: keybox /root/.gnupg/pubring.kbx created
gpg: /root/.gnupg/trustdb.gpg: trustdb created
Generate keys
gpg: no running gpg-agent - starting /usr/bin/gpg-agent
gpg: waiting for the agent to come up ... (5s)
gpg: connection to agent established
gpg: writing self signature
gpg: RSA/SHA512 signature from: "C8338E605AB8E7E4 [?]"
gpg: writing key binding signature
gpg: RSA/SHA512 signature from: "C8338E605AB8E7E4 [?]"
gpg: RSA/SHA512 signature from: "04FD871034B69D9D [?]"
gpg: writing public key to /root/.gnupg/pubring.kbx
gpg: using pgp trust model
gpg: directory /root/.gnupg/openpgp-revocs.d created
gpg: writing to /root/.gnupg/openpgp-revocs.d/B653C89FC6B35C84A5B85CA7C8338E605AB8E7E4.rev
gpg: RSA/SHA512 signature from: "C8338E605AB8E7E4 Ali (Alis account) <ali@example.com>"
gpg: revocation certificate stored as /root/.gnupg/openpgp-revocs.d/B653C89FC6B35C84A5B85CA7C8338E605AB8E7E4.rev
Backup public and private keys
done
Backup trust database
done
Cleanup
done
> GENERATE USERs PUBLIC and PRIVATE KEYS (end) ------------------------------------------

Anahtarı şifrele


Gönderenin, alıcının şifresini çözmesi için düz bir mesajı şifrelemesine yardımcı olur. Gönderenin düz mesajı /users/{sender_name}/msg-to-encrypt.txt dosyasına yerleştirilmelidir. Başarılı işlem, şifreli mesajı /users/{sender_name}/encrypted-msg.txt dosyasına yerleştirecektir. Bu dosya, şifre çözme için ortak anahtarınıza sahip olan alıcı ile paylaşılabilir.


$ make enc-msg SENDER=ali RECEIVER=bob

> SENDER ENCRYPTS a PLAIN MESSAGE for RECEIVER to DECRYPT (begin) ------------------------
Set local variables
done
Create gpg directory and get into it
gpg: directory /root/.gnupg created
gpg: keybox /root/.gnupg/pubring.kbx created
gpg: /root/.gnupg/trustdb.gpg: trustdb created
Restore senders public key
gpg: key C8338E605AB8E7E4: public key "Ali (Alis account) <ali@example.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
Restore senders private key
gpg: key C8338E605AB8E7E4: "Ali (Alis account) <ali@example.com>" not changed
gpg: key C8338E605AB8E7E4: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
Restore senders trust database
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: inserting ownertrust of 6
Restore receivers public key
gpg: key 6BA9B4E9279E259C: public key "Bob (Bobs account) <bob@example.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
Verify receivers public key
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub rsa2048 2022-06-03 [SCEA]
E464 CA1D C0A4 A8F5 D473 0160 6BA9 B4E9 279E 259C
uid [ unknown] Bob (Bobs account) <bob@example.com>
sub rsa2048 2022-06-03 [SEA]

Sign receivers public key

pub rsa2048/6BA9B4E9279E259C
created: 2022-06-03 expires: never usage: SCEA
trust: unknown validity: unknown
sub rsa2048/8C840512707375BB
created: 2022-06-03 expires: never usage: SEA
[ unknown] (1). Bob (Bobs account) <bob@example.com>


pub rsa2048/6BA9B4E9279E259C
created: 2022-06-03 expires: never usage: SCEA
trust: unknown validity: unknown
Primary key fingerprint: E464 CA1D C0A4 A8F5 D473 0160 6BA9 B4E9 279E 259C

Bob (Bobs account) <bob@example.com>

Are you sure that you want to sign this key with your
key "Ali (Alis account) <ali@example.com>" (C8338E605AB8E7E4)

Really sign? (y/N) y

Sender encrypts message for receiver
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u
done
Cleanup
done
> SENDER ENCRYPTS a PLAIN MESSAGE for RECEIVER to DECRYPT (end) --------------------------

Anahtarın şifresini çözme


Alıcının, gönderenin şifreli mesajının şifresini çözmesine yardımcı olur. Gönderenin şifreli mesajı /users/{receiver_name}/msg-to-decrypt.txt dosyasına yerleştirilmelidir. Başarılı işlem, şifresi çözülen mesajı /users/{receiver_name}/decrypted-msg.txt dosyasına koyacaktır.


$ make dec-msg SENDER=ali RECEIVER=bob

> RECEIVER DECRYPTS SENDERs ENCRYPTED MESSAGE (begin) -----------------------------------
Set local variables
done
Create gpg directory and get into it
gpg: directory /root/.gnupg created
gpg: keybox /root/.gnupg/pubring.kbx created
gpg: /root/.gnupg/trustdb.gpg: trustdb created
Restore receivers public key
gpg: key 6BA9B4E9279E259C: public key "Bob (Bobs account) <bob@example.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
Restore receivers private key
gpg: key 6BA9B4E9279E259C: "Bob (Bobs account) <bob@example.com>" not changed
gpg: key 6BA9B4E9279E259C: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
Restore receivers trust database
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: inserting ownertrust of 6
Restore senders public key
gpg: key C8338E605AB8E7E4: public key "Ali (Alis account) <ali@example.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
Verify senders public key
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub rsa2048 2022-06-03 [SCEA]
B653 C89F C6B3 5C84 A5B8 5CA7 C833 8E60 5AB8 E7E4
uid [ unknown] Ali (Alis account) <ali@example.com>
sub rsa2048 2022-06-03 [SEA]

Sign senders public key

pub rsa2048/C8338E605AB8E7E4
created: 2022-06-03 expires: never usage: SCEA
trust: unknown validity: unknown
sub rsa2048/04FD871034B69D9D
created: 2022-06-03 expires: never usage: SEA
[ unknown] (1). Ali (Alis account) <ali@example.com>


pub rsa2048/C8338E605AB8E7E4
created: 2022-06-03 expires: never usage: SCEA
trust: unknown validity: unknown
Primary key fingerprint: B653 C89F C6B3 5C84 A5B8 5CA7 C833 8E60 5AB8 E7E4

Ali (Alis account) <ali@example.com>

Are you sure that you want to sign this key with your
key "Bob (Bobs account) <bob@example.com>" (6BA9B4E9279E259C)

Really sign? (y/N) y

Receiver decrypts senders encrypted message
gpg: encrypted with 2048-bit RSA key, ID 8C840512707375BB, created 2022-06-03
"Bob (Bobs account) <bob@example.com>"
gpg: Signature made Fri Jun 3 20:44:12 2022 UTC
gpg: using RSA key 4B874F8387E97D9044FF8A4B04FD871034B69D9D
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u
gpg: Good signature from "Ali (Alis account) <ali@example.com>" [full]
Cleanup
done
> RECEIVER DECRYPTS SENDERs ENCRYPTED MESSAGE (end) -------------------------------------