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

105

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

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

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

我搜索了一下,但没有找到可行的解决方案...例如:
如何为AWS Elastic Beans设置多行RSA私钥环境变量

image

错误: -----END RSA PRIVATE KEY-----': 不是一个有效的标识符 按照以下说明进行操作: 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 'BEGIN{}{out=out$0"\n"}END{print out}' $file| sed 's/\n$//')"

image 然后运行以下命令:

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

那个方法可行,但似乎是一种繁琐的方式...
有人知道更简单的方法吗? (我希望有一种适合初学者的解决方案,不要太多步骤...)

2
你的 .sh 脚本出了问题:你试图通过引用/值来 export $var,但应该改为通过名称 export var。无论如何,答案很简单:bash 允许多行字符串字面量,只要它们被引用。可以使用单引号或双引号。 - MarkHu
@MarkHu,你的方法不起作用。 - SFin
除非我误解了我所看到的内容,否则你已经在 Stack Overflow 上公开了一个私钥供全世界查看。虽然已经过去一年了,但如果这个密钥仍然有效,你应该更改它。 - rp.beltran
@rp.beltran,密钥长度不足以成为有效的RSA私钥。但是谢谢关心。 :-) - nelsonic
1
好的观点,我的错误。 - rp.beltran
6个回答

120
导出密钥
export PRIVATE_KEY=`cat ./gitbu.2018-03-23.private-key.pem`

test.sh

#!/bin/bash

echo "$PRIVATE_KEY"; 

注意:上面的echo中的"是必需的 - 否则换行将被转换为空格!

如果你想将密钥保存到.env文件中与其他环境变量一起,你只需要在.env文件中用单引号将私钥字符串"包裹"起来...例如: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文件时,它将被导出。

6
如此回答中所述,https://dev59.com/N1UM5IYBdhLWcg3wAsjv#53271334,`echo $PRIVATE_KEY` 有时会在显示输出时剥离所有换行符。我认为这取决于可能版本或echo的shell。但是如果用双引号括起来,示例将更好和更准确。 - Elijah Lynn
1
还有一点需要注意,我刚刚意识到,env 命令总是正确地显示变量,并且带有换行符。 - Elijah Lynn
当我尝试从.env文件访问我的密钥时,它只返回第一行“-----BEGIN RSA PRIVATE KEY-----”。 - Marcelo Fonseca
在这种情况下,我只获取密钥文件的最后一行。 - Aman Prakash
1
我在Glitch项目中使用.env文件,将密钥用单引号括起来是唯一有效的解决方案...我已经搜索了一段时间,所以谢谢! - Tristan Bennett
在大多数应用程序中,评估.env中的变量并不是一个选项。例如,在Kubernetes服务中想象一下加密的私钥。正如在此线程的结尾所建议的那样:https://github.com/dwyl/learn-environment-variables/issues/17,最好的选择是使用base64对密钥进行编码,并在访问时解码它。 - Klamber

49

如果你想导出直接值(不是从*.pem文件中获取),那么在等号后使用"。终端会让你用另一个"完成。

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

3
我尝试了相同的事情,但是它读取的不是完整密钥而是"-----BEGIN RSA PRIVATE KEY----- - Wasif Ali
@WasifAli 你真的在 -----END RSA PRIVATE KEY----- 后面放了 " 吗? - Amio.io
2
是的,我尝试过这个方法,但它没有起作用。对我有效的方法是将所有换行符替换为 '\n' 字符。 - Wasif Ali

26
注意:为了让输出正确运行,我不得不将环境变量用双引号括起来。否则,它会将换行符替换为空格。

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

输出:

echo "$PRIVATE_KEY"

4
天啊!太好了,我一直在检查一个没有引号的变量,结果只得到了一行(echo $TEST | wc --lines)。我都快疯了!感谢你的建议,非常有帮助,让我确定它确实包含了所有的行。 - Elijah Lynn
2
还有一点需要注意,我刚刚意识到,env 命令总是正确地显示变量,并且带有换行符。 - Elijah Lynn

17
我所需要的是只有一个可执行Shell脚本,而不是一个脚本和一个.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行字符串转换回其原始姿态并写入临时文件。

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文件夹中,其他使用同一台服务器的用户也可以读取。

1
将密钥进行Base64编码对我来说也是最佳解决方案。 - jakxnz
1
cat id_rsa | base64 -w0 这真是救命稻草。谢谢! - Jithesh Kt

9
.env文件中添加RSA密钥。
第一步。
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"

第二步。打印PRIVATE_KEY只显示第一行。 将变量更改为单行。像这样:
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\ndasdasdadasdasdasdasdasdasdasdadasdasdadasa\nhuehuauhhuauhahuauhauahuauhehuehuauheuhahue\n-----END RSA PRIVATE KEY-----\n"

如果在应用程序中使用密钥,例如 node。
process.env.PRIVATE_KEY 将被正确输出。

7

我想补充的是,一种更加优雅和可靠的方式是将环境变量编码为base64格式,然后在访问时解码。

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

一钉定了!这完美地运行了。我在NestJS中使用它从configModule获取,这正是我所需要的,谢谢! - DustInTheSilence
就此而言,AWS Lambda 对环境变量有限制,如果使用 base64 编码,私钥很可能会太长。 - jseashell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接