包含Node中换行符的环境变量?

时间:2015-05-22 15:16:38

标签: node.js escaping environment-variables

我尝试使用环境变量将RSA私钥加载到我的nodejs应用程序中,但新行似乎正在自动转义。

对于以下内容,假设PRIVATE_KEY env var设置为以下(不是我的实际密钥):

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp\nwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5\n1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh\n3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2\npIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX\nGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il\nAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF\nL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k\nX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl\nU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ\n37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=\n-----END RSA PRIVATE KEY-----"

如果我直接用前面的字符串调用console.log,我会得到以下输出:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----

您可以看到新行字符正在受到尊重。但是,如果我调用console.log(process.env["PRIVATE_KEY"]),则输出包含\n字面值而非实际换行符:

-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp\nwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5\n1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh\n3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2\npIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX\nGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il\nAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF\nL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k\nX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl\nU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ\n37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=\n-----END RSA PRIVATE KEY-----

我一直试图在网上找到有关节点如何处理环境变量而没有运气的更多信息。如何在维护换行符时通过env变量加载此密钥?如果那不可能,我该如何恢复它们?

8 个答案:

答案 0 :(得分:42)

在使用值之前,只需替换\n

var private_value = process.env.PRIVATE_KEY.replace(/\\n/g, '\n');
console.log(private_value);

将正确结果:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----

答案 1 :(得分:5)

Node.js, 正确反映嵌入了实际换行符的环境变量,如下面的bash代码段所示:

$ PRIVATE_KEY=$'ab\ncde' node -p 'process.env["PRIVATE_KEY"].indexOf("\n")'
2  # 0-based index of the (first) actual newline char. in env. var. 'PRIVATE_KEY'

请注意,$'...'是一种特殊类型的bash字符串,其中\n 等转义序列已扩展,因此在上面的命令中PRIVATE_KEY确实用 2 行定义,并作为环境变量传递给node(只需将变量赋值预先添加到要调用的命令,这是POSIX中的标准功能) - 像贝壳)。

事实上, Node并没有以任何方式解释环境变量的值(这是正确的做法)。

您的PRIVATE_KEY变量必须不包含实际换行符,但\n 文字(a { {1}} char。后跟char。\)。

  • 如果问题中的赋值命令n shell 命令,那就可以解释它:在类似POSIX的shell中,例如PRIVATE_KEY="...",{{ 1}} bash字符串内的

    • 相比之下, JavaScript \n字符串执行插入转义序列,例如"...",这就是将此类字符串直接传递给{{}的原因1}}确实输出换行符;例如,"..."确实输出 2 行。
  • \n(字面意思)输出console.log(),显示node -e 'console.log("ab\ncde")'保留为文字。

您有两种方法可以解决问题:

  • 最好使用实际新行来定义您的环境变量 - 请参阅下文。

  • 或者,如果您不控制环境变量的设置方式,请将PRIVATE_KEY="ab\ncde" node -p 'process.env["PRIVATE_KEY"]'文字扩展为Node.js(JavaScript)代码中的实际换行符:请参阅{ {3}}

使用类似POSIX的shell中的实际换行符定义ab\ncde ,请使用以下技术之一:

bash
  • 其他人,例如ksh(以及使用zsh的任何shell脚本):
export PRIVATE_KEY=$'-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----'

或者,为了更好的可读性,您可以使用here-document:

命令替换
dash

答案 2 :(得分:5)

如果你正在使用 dotenv :我们用这种方式解决了这个问题,使用换行符和JSON.parse(这允许字符串中的任何反斜杠转义字符,而不仅仅是\n ):

in .env:

MY_KEY='-----BEGIN CERTIFICATE-----\nabcde...'

在server.ts中:

myKey = JSON.parse(`"${process.env.MY_KEY}"`), // convert special chars

见线程:https://github.com/motdotla/dotenv/issues/218

答案 3 :(得分:4)

Node将获取环境变量并将其转义以避免插值:

% export X="hey\nman"
% echo $X
hey
man
% node
> process.env['X']
'hey\\nman'
>

一个选项是使用实际换行符在节点外部设置变量:

% export X="hey
dquote> man"
% node
> process.env['X']
'hey\nman'
> console.log(process.env['X'])
hey
man
undefined
>

这也适用于脚本文件,只需在引号内使用换行符。您也可以进行替换:

% export X="hey\nman\ndude\nwhat"
% node
> console.log(process.env['X'].replace(/\\n/g, '\n'))
hey
man
dude
what

答案 4 :(得分:3)

如另一个主题所述,您可以在base64中对多行字符串进行编码,然后将其放入.env之内

HTTPS_CA_CERTIFICATE=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURDVENDQWZHZ0F3SUJBZ0lVY29lWFp1R

然后在您的应用中对其进行解码

var cert = new Buffer(process.env.HTTPS_CA_CERTIFICATE, 'base64').toString('ascii');

答案 5 :(得分:0)

dotenv支持带双引号的换行符:

  

双引号引起来的新行(MULTILINE =“ new \ nline”变为

{MULTILINE: 'new
line'}

答案 6 :(得分:0)

我正在使用:

JSON.parse(`"${process.env.PUBPEM}"`)

突然开始失败。 所以我将其更改为:

JSON.parse(JSON.stringify(process.env.PUBPEM))

哪个为我解决了。

答案 7 :(得分:0)

为了让任何试图在dotenv文件中使用多行变量(即RSA私钥)的人都受益(尽管对于任何配置文件都应如此)。

1)使私钥的每一行都以\ n

结尾
  such that first line**\n**
  second line**\n**
  and the  third line and so on

2)现在使变量在单行中用双引号引起,如下所示   KEY =“,这样第一行** \ n 第二行 \ n ,第三行以此类推 \ n **”

3)确保,您还为键添加了开头和结尾的\ n字符 KEY =“ \ n ,例如第一行** \ n 第二行 \ n 和第三行,依此类推 \ n **”

4)现在在您的代码中(即节点,当然,如果您无权访问代码,则取决于平台/应用程序的行为)

goodlyRepresentedKey =(process.env.KEY).replace(/ \ n / g,'\ n');

(如果大,为什么不好)