如果你不想在你的设备上安装GPG/PGP来使用其命令,你可以尝试下面的Docker设置。通过目前的设置,你可以对信息进行加密和解密。唯一可以添加的是,文件加密和解密应该很容易。
无论你是发送方还是接收方,你都会被提示输入你的密码,用于make 命令。每个用户(测试)的个人资料都在.env.dist ,使用示例值。对于真正的用户,这个文件必须被复制为.env ,并包含真实的值。这个文件被排除在VCS提交以及/users/ 文件夹之外!
结构
这是原始状态:
├── .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作为发送方/接收方并运行以下命令后得到的结果:
├── .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
文件
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
制作文件
.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
命令
生成密钥
它创建公钥和私钥,然后将它们备份到/users/{name}/ 文件夹中,包括 "信任 "数据库。创建的文件是private.key,public.key 和trust.db 。然后,public.key 可以与第三方共享,以解密信息:
$ 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) ------------------------------------------
加密密钥
它可以帮助发送者为接收者解密的明文信息进行加密。发送方的明文信息必须放到/users/{sender_name}/msg-to-encrypt.txt 文件中。成功的操作将把加密的信息放入/users/{sender_name}/encrypted-msg.txt 文件。这个文件可以与拥有你的公钥的接收者共享,以便解密:
$ 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) ---------------------
解密密钥
它帮助接收方解密发送方的加密信息。发送方的加密信息必须放到/users/{receiver_name}/msg-to-decrypt.txt 文件中。成功的操作将把解密的信息放入/users/{receiver_name}/decrypted-msg.txt 文件:
$ 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) -------------------------------------