如何在 bash 中安全地使用私钥?

How to work with private keys securely in bash?

如何在 bash 脚本中安全地使用私钥?我的第一次尝试涉及将加密的密钥对存储在数据库的一个字段中 (mongo)。但是,我已经意识到我必须在 bash 脚本中使用这些密钥,在解密之后,以便 scp 或 ssh(密钥必须是一个文件,所以这也会增加 IO)。

这发生在高山 linux 容器内。我应该担心在包含键的字符串上使用 echo 吗?

我还考虑过将密钥作为文件(id_rsa、id_rsa.pub)存储在容器卷中,并在数据库中引用这些路径(或对路径进行硬编码)。我正在使用很多密钥对,从 DB 到 UI 再到 API(3 个单独的容器)再到 BASH(在 API 容器中)以创建连接和在这些主机中的每一个上执行功能。这有助于解决 IO 问题。

有更好的方法吗?我应该使用某种可以在我的数据库中存储引用的密钥库吗?

按重要性排序,安全 - 低 IO - 高效率。

感谢@Philippe 建议使用 PGP! 我的解决方案是:

使用此脚本创建主密钥:

#!/bin/bash
cd ~/
mv .gnupg .gnupg.bak
echo "Existing keys were moved to '.gnupg.bak'."
# rm -rf .gnupg
mkdir -m 0700 .gnupg
touch .gnupg/gpg.conf
chmod 600 .gnupg/gpg.conf
echo << EOF >  .gnupg/gpg.conf
################################################################################
# GnuPG Options

# (OpenPGP-Configuration-Options)
# Assume that command line arguments are given as UTF8 strings.
utf8-strings

# (OpenPGP-Protocol-Options)
# Set the list of personal digest/cipher/compression preferences. This allows 
# the user to safely override the algorithm chosen by the recipient key 
# preferences, as GPG will only select an algorithm that is usable by all 
# recipients.
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
personal-cipher-preferences AES256 AES192 AES CAST5 CAMELLIA192 BLOWFISH TWOFISH CAMELLIA128 3DES
personal-compress-preferences ZLIB BZIP2 ZIP

# Set the list of default preferences to string. This preference list is used 
# for new keys and becomes the default for "setpref" in the edit menu. 
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed

# (OpenPGP-Esoteric-Options)
# Use name as the message digest algorithm used when signing a key. Running the 
# program with the command --version yields a list of supported algorithms. Be 
# aware that if you choose an algorithm that GnuPG supports but other OpenPGP 
# implementations do not, then some users will not be able to use the key 
# signatures you make, or quite possibly your entire key.
# 
# SHA-1 is the only algorithm specified for OpenPGP V4. By changing the 
# cert-digest-algo, the OpenPGP V4 specification is not met but with even 
# GnuPG 1.4.10 (release 2009) supporting SHA-2 algorithm, this should be safe.
# Source: https://tools.ietf.org/html/rfc4880#section-12.2
cert-digest-algo SHA512
digest-algo SHA256

# Selects how passphrases for symmetric encryption are mangled. 3 (the default) 
# iterates the whole process a number of times (see --s2k-count).
s2k-mode 3

# (OpenPGP-Protocol-Options)
# Use name as the cipher algorithm for symmetric encryption with a passphrase 
# if --personal-cipher-preferences and --cipher-algo are not given. The 
# default is AES-128. 
s2k-cipher-algo AES256

# (OpenPGP-Protocol-Options)
# Use name as the digest algorithm used to mangle the passphrases for symmetric 
# encryption. The default is SHA-1. 
s2k-digest-algo SHA512

# (OpenPGP-Protocol-Options)
# Specify how many times the passphrases mangling for symmetric encryption is 
# repeated. This value may range between 1024 and 65011712 inclusive. The 
# default is inquired from gpg-agent. Note that not all values in the 
# 1024-65011712 range are legal and if an illegal value is selected, GnuPG will 
# round up to the nearest legal value. This option is only meaningful if 
# --s2k-mode is set to the default of 3. 
s2k-count 1015808

################################################################################
# GnuPG View Options

# Select how to display key IDs. "long" is the more accurate (but less 
# convenient) 16-character key ID. Add an "0x" to include an "0x" at the 
# beginning of the key ID.
keyid-format 0xlong

# List all keys with their fingerprints. This is the same output as --list-keys 
# but with the additional output of a line with the fingerprint. If this 
# command is given twice, the fingerprints of all secondary keys are listed too.
with-fingerprint
with-fingerprint

# Use gpg-agent for SSH instead of ssh-agent
use-agent
EOF

cd .gnupg

cat >master <<EOF
    %echo Generating Master PGP key
    Key-Type: RSA
    Key-Length: 4096
    Subkey-Type: RSA
    Subkey-Length: 4096
    Name-Real: Master
    Name-Comment: Master
    Name-Email: master@demo.keys
    Expire-Date: 0
    %no-ask-passphrase
    %no-protection
    %pubring pubring.kbx
    %secring trustdb.gpg
    %commit
EOF

gpg2 --verbose --no-greeting --batch --gen-key master
echo -e "5\ny\n" |  gpg2 --command-fd 0 --expert --no-greeting --batch --edit-key master@demo.keys trust;
echo "Master key has been created and verified. :)" > TESTFILE
gpg2 -e -a -r master@demo.keys TESTFILE
rm TESTFILE
rm master
gpg2 -d TESTFILE.asc
rm TESTFILE.asc

使用此脚本创建子键:

#!/bin/bash
echo -e "addkey\n8\nS\nA\nQ\n4096\n0\nsave" |  gpg2 \
    --command-fd 0 --verbose --no-greeting --expert --edit-key --batch --passphrase "" master@demo.keys;
fingerprints=$(gpg2 --list-keys --with-subkey-fingerprint | grep "      " | sed 's/      //g')
fingerprint=$(echo $fingerprints | awk '{print $NF}')
publicId=$(echo ${fingerprint: -8})
fingerprint=$(echo $fingerprints | awk '{print }')
privateId=$(echo ${fingerprint: -8})
echo "Using master key with ID:"
echo $privateId
echo "Sub key added with ID:"
echo $publicId

并将最后一个脚本打印的 ID 存储在 mongo 中,master 为 'private',sub 为 'public'。

使用 gpg2 --export-secret-key $ID | ssh $REMOTE_MACHINE gpg2 --import

将 public 授权密钥发送到远程主机