如何在 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 授权密钥发送到远程主机
如何在 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