如何在 Bash/Terminal 中导出多行环境变量,例如:RSA 私钥

Posted

技术标签:

【中文标题】如何在 Bash/Terminal 中导出多行环境变量,例如:RSA 私钥【英文标题】:How to Export a Multi-line Environment Variable in Bash/Terminal e.g: RSA Private Key 【发布时间】:2018-09-02 14:38:42 【问题描述】:

我们的一个应用程序github-backup 需要使用 RSA 私钥作为环境变量。

只需尝试在终端中导出密钥,例如: text export PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA04up8hoqzS1+ ... l48DlnUtMdMrWvBlRFPzU+hU9wDhb3F0CATQdvYo2mhzyUs8B1ZSQz2Vy== -----END RSA PRIVATE KEY-----

不起作用...因为换行符。

我做了一些谷歌搜索,但没有找到可行的解决方案... 例如:How to set multiline RSA private key environment variable for AWS Elastic Beans

错误: -----END RSA PRIVATE KEY-----': not a valid identifier

按照以下说明进行操作: http://blog.vawter.com/2016/02/10/Create-an-Environment-Variable-from-a-Private-Key

使用以下行创建了一个名为 keytoenvar.sh 的文件:

#!/usr/bin/env bash
file=$2
name=$1
export $name="$(awk 'BEGINout=out$0"\n"ENDprint out' $file| sed 's/\n$//')"

然后运行以下命令:

source keytoenvar.sh PRIVATE_KEY ./gitbu.2018-03-23.private-key.pem

有效,但它似乎是一种“冗长”的方法...... ????

有谁知道更简单的方法? (我希望没有太多“步骤”的“初学者友好”解决方案......

【问题讨论】:

您的 .sh 脚本有问题:您尝试使用 export $var(按引用/值)但应该改为 export var(按名称)。无论如何,答案很简单:bash 允许多行字符串文字,只要它们被引用。使用单引号或双引号。 @MarkHu 你的方法不起作用。 除非我误解了我正在查看的内容,否则您已经在 Stack Overflow 上发布了一个私钥供全世界查看。已经一年了,但如果此密钥仍然有效,您应该更改它。 @rp.beltran 密钥不够长,不能成为有效的 RSA 私钥。但感谢您的关心。 :-) 好点,我的坏 【参考方案1】:

导出密钥

export PRIVATE_KEY=`cat ./gitbu.2018-03-23.private-key.pem`

test.sh

#!/bin/bash

echo "$PRIVATE_KEY"; 

如果您想将密钥与其余环境变量一起保存到 .env 文件中,您所需要做的就是将私钥字符串“包装”在 @ 中的 单引号 中987654325@ 文件... 例如:sh exports HELLO_WORLD='-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA04up8hoqzS1+APIB0RhjXyObwHQnOzhAk5Bd7mhkSbPkyhP1 ... iWlX9HNavcydATJc1f0DpzF0u4zY8PY24RVoW8vk+bJANPp1o2IAkeajCaF3w9nf q/SyqAWVmvwYuIhDiHDaV2A== -----END RSA PRIVATE KEY-----' 所以下面的命令会起作用:

echo "export PRIVATE_KEY='`cat ./gitbu.2018-03-23.private-key.pem`'" >> .env

接着是:

source .env

现在密钥将在您的 .env 文件中,并且无论何时您获取 .env 文件,它都会被导出。

【讨论】:

如本答案中所述,***.com/a/53271334/292408,echo $PRIVATE_KEY 在显示输出时有时会删除所有换行符。我认为这取决于版本或回声的外壳。但是如果用双引号括起来,这个例子会更好更准确。 另外值得注意的是,我刚刚意识到,env 总是用换行符正确显示变量。 当我尝试从 .env 文件访问我的密钥时,它只返回第一行'-----BEGIN RSA PRIVATE KEY-----' 在这种情况下,我只获取密钥文件的最后一行 我正在使用 .env 文件和 Glitch 中的一个项目,并且将密钥括在单引号中是唯一对我有用的解决方案......我一直在寻找一段时间,所以谢谢!! 【参考方案2】:

注意:为了让输出正常工作,我必须将环境变量用双引号引起来。否则它会用空格替换换行符。

在:

export PRIVATE_KEY=$(cat ./gitbu.2018-03-23.private-key.pem)

输出:

echo "$PRIVATE_KEY"

【讨论】:

该死!!!太好了,我一直在检查没有引号的变量并一直得到 1 行 (echo $TEST | wc --lines)。而且快疯了!!!感谢您提出这个建议,非常有助于确定它实际上确实包含所有行。 另外值得注意的是,我刚刚意识到,env 总是用换行符正确显示变量。【参考方案3】:

如果您想导出直接值(不是来自 *.pem),请在等号后使用 "。终端将让您以另一个 " 结束。

export PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA04up8hoqzS1+
...
l48DlnUtMdMrWvBlRFPzU+hU9wDhb3F0CATQdvYo2mhzyUs8B1ZSQz2Vy==
-----END RSA PRIVATE KEY-----"

【讨论】:

我也尝试过,但不是读取完整的密钥,而是将其读取为"-----BEGIN RSA PRIVATE KEY----- @WasifAli 你真的把"放在-----END RSA PRIVATE KEY-----之后吗? 是的,我已经尝试过了,它没有用,所以对我有用的是将所有新行替换为 '\n' 字符。【参考方案4】:

我想要的是一个且只有一个包含所有内容的可执行 shell 脚本,而不是 1 个脚本和 1 个 .pem 文件,然后在两者之间做一些体操,就像我目前在现有答案中看到的那样。

要实现这种统一,只需要以下内容。准备阶段:

cat id_rsa | base64 -w0
# assign the converted 1-liner string wrap in single quote into a shell variable, for example
pk='xxxxxxxxxxxyyyyyyyyyyzzzzzzzzzzz......'

剩下的就是在公园里散步。要使用变量pk ssh,您需要将 1-liner 字符串转换回其原始状态并写入临时文件。

t=$(mktemp ~/temp.XXXXXXXXXX)
printf $pk | base64 --decode > $t
ssh -i $t smeagol@192.143.69.69

要在您的 shell 脚本退出时清理临时文件,请添加一个 shell trap 处理程序:

trap cleanup 1 2 3 6
cleanup () 
    rm -f $t

为了提高安全性,请注意mktemp ~/temp.XXXXXXXXXX 的使用,以便临时文件写入您的$HOME 文件夹中只有您可以阅读的位置,而不是系统范围内的/tmp 文件夹中其他用户在同一服务器中可以阅读。

【讨论】:

base64 编码密钥对我来说也是最好的解决方案 cat id_rsa | base64 -w0 这是救命稻草。谢谢!【参考方案5】:

您也可以使用 bash heredoc:

export MY_CERTIFICATE=$(cat <<EOF
-----BEGIN CERTIFICATE-----
qiuwiuwoejqododhIOOISOIIOiiSNIDNIDINDIONDIND
DDHDHUDHDUHUhudhHQhhqoohooiiohihiohihhihhihi
dhdiodhioho...
-----END CERTIFICATE-----
EOF
)

设置后,您可以将其作为常规环境变量echo "$MY_CERTIFICATE" 访问。

【讨论】:

我试过了,但是证书在一行,没有断行。 @max johnson:这只是因为缺少撇号。试试echo "$MY_CERTIFICATE"。那应该可以。 有史以来最简单的最佳解决方案!【参考方案6】:

将 RSA 密钥添加到 .env 文件。

第 1 步。

echo "PRIVATE_KEY=\"`sed -E 's/$/\\\n/g' my_rsa_2048_priv.pem`\"" >> .env

.env 文件中的密钥将如下所示:

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n
dasdasdadasdasdasdasdasdasdasdadasdasdadasa\n
huehuauhhuauhahuauhauahuauhehuehuauheuhahue\n
-----END RSA PRIVATE KEY-----\n"

步骤 2. 打印 PRIVATE_KEY 只显示第一行。 将变量更改为单行。像这样:

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\ndasdasdadasdasdasdasdasdasdasdadasdasdadasa\nhuehuauhhuauhahuauhauahuauhehuehuauheuhahue\n-----END RSA PRIVATE KEY-----\n"

如果在应用内使用密钥 例如node.process.env.PRIVATE_KEY 将正确输出。

【讨论】:

【参考方案7】:

我要补充一点,一种更优雅的万无一失的方法是将 env var 编码为 base64,然后在访问时对其进行解码。

const base64 = process.env.GITHUB_PRIVATE_KEY
const privateKey = Buffer.from(base64, 'base64')

【讨论】:

以上是关于如何在 Bash/Terminal 中导出多行环境变量,例如:RSA 私钥的主要内容,如果未能解决你的问题,请参考以下文章

在 bash 脚本中导出数组

如何使用 setenv() 在 C++ 中导出变量?

在 VSCODE 中导入语句自动转换为多行

如何“从 python 脚本中导出 CFLAGS='my -flags -here'

似乎可以从 bash 脚本中导出环境变量

从带有参数的bash脚本中导出环境变量