How to Export a Multi-line Environment Variable in Bash/Terminal e.g: RSA Private Key
BashShellEnvironment VariablesMultilinePrivate KeyBash Problem Overview
One of our Apps github-backup
requires the use of an RSA Private Key as an Environment Variable.
Simply attempting to export the key it in the terminal e.g:
export PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA04up8hoqzS1+
...
l48DlnUtMdMrWvBlRFPzU+hU9wDhb3F0CATQdvYo2mhzyUs8B1ZSQz2Vy==
-----END RSA PRIVATE KEY-----
Does not work ... because of the line breaks.
I did a bit of googling but did not find a workable solution ...
e.g: https://stackoverflow.com/questions/43082918/how-to-sett-multiline-rsa-private-key-environment-variable-for-aws-elastic-beans
Error:
-----END RSA PRIVATE KEY-----': not a valid identifier
followed the instructions in: http://blog.vawter.com/2016/02/10/Create-an-Environment-Variable-from-a-Private-Key
Created a file called keytoenvar.sh
with the following lines:
#!/usr/bin/env bash
file=$2
name=$1
export $name="$(awk 'BEGIN{}{out=out$0"\n"}END{print out}' $file| sed 's/\n$//')"
then ran the following command:
source keytoenvar.sh PRIVATE_KEY ./gitbu.2018-03-23.private-key.pem
That works but it seems like a "long-winded" approach ... 樂
Does anyone know of a simpler way of doing this?
(I'm hoping for a "beginner friendly" solution without too many "steps"...)
Bash Solutions
Solution 1 - Bash
export the key
export PRIVATE_KEY=`cat ./gitbu.2018-03-23.private-key.pem`
test.sh
#!/bin/bash
echo "$PRIVATE_KEY";
If you want to save the key to a .env
file with the rest of your environment variables, all you needed to do is "wrap" the private key string in single quotes in the .env
file ... e.g: sh exports HELLO_WORLD='-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA04up8hoqzS1+APIB0RhjXyObwHQnOzhAk5Bd7mhkSbPkyhP1 ... iWlX9HNavcydATJc1f0DpzF0u4zY8PY24RVoW8vk+bJANPp1o2IAkeajCaF3w9nf q/SyqAWVmvwYuIhDiHDaV2A== -----END RSA PRIVATE KEY-----'
So the following command will work:
echo "export PRIVATE_KEY='`cat ./gitbu.2018-03-23.private-key.pem`'" >> .env
Followed by:
source .env
Now the key will be in your .env file and whenever you source .env it will be exported.
Solution 2 - Bash
If you want to export direct value (not from *.pem) then use "
after equals sign. The terminal will let you finish with another "
.
export PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA04up8hoqzS1+
...
l48DlnUtMdMrWvBlRFPzU+hU9wDhb3F0CATQdvYo2mhzyUs8B1ZSQz2Vy==
-----END RSA PRIVATE KEY-----"
Solution 3 - Bash
NOTE: For me to get the output to work correctly, I had to wrap the environment variable in double quotes. Otherwise it replaced newlines with spaces.
In:
export PRIVATE_KEY=$(cat ./gitbu.2018-03-23.private-key.pem)
Out:
echo "$PRIVATE_KEY"
Solution 4 - Bash
You can also use a bash heredoc:
export MY_CERTIFICATE=$(cat <<EOF
-----BEGIN CERTIFICATE-----
qiuwiuwoejqododhIOOISOIIOiiSNIDNIDINDIONDIND
DDHDHUDHDUHUhudhHQhhqoohooiiohihiohihhihhihi
dhdiodhioho...
-----END CERTIFICATE-----
EOF
)
Once you set it you can access it as a regular env variable echo "$MY_CERTIFICATE"
.
Solution 5 - Bash
What I wanted is one and only one executable shell script containing it all, and not 1 script and 1 .pem
file and then doing some gymnastics in between, like what I am seeing in the existing answers so far.
To achieve this unification, all that is needed is the following. Preparation phase:
cat id_rsa | base64 -w0
# assign the converted 1-liner string wrap in single quote into a shell variable, for example
pk='xxxxxxxxxxxyyyyyyyyyyzzzzzzzzzzz......'
The rest is walk-in-the park. To ssh using variable pk
you will convert back the 1-liner string into its original posture and write to a temporary file.
t=$(mktemp ~/temp.XXXXXXXXXX)
printf $pk | base64 --decode > $t
ssh -i $t [email protected]
To clean-up the temporary file when your shell script exits, add a shell trap
handler:
trap cleanup 1 2 3 6
cleanup () {
rm -f $t
}
To improve security, notice the use of mktemp ~/temp.XXXXXXXXXX
so the temporary file is written somewhere within your $HOME
folder where only you can read, rather than in a system wide /tmp
folder where other users in the same server can read.
Solution 6 - Bash
Adding a RSA key to an .env
file.
Step 1.
echo "PRIVATE_KEY=\"`sed -E 's/$/\\\n/g' my_rsa_2048_priv.pem`\"" >> .env
Your key in the .env
file will look something like this:
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n
dasdasdadasdasdasdasdasdasdasdadasdasdadasa\n
huehuauhhuauhahuauhauahuauhehuehuauheuhahue\n
-----END RSA PRIVATE KEY-----\n"
Step 2. Printing PRIVATE_KEY
only show the first line.
Change the variable to a single line. Like this:
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\ndasdasdadasdasdasdasdasdasdasdadasdasdadasa\nhuehuauhhuauhahuauhauahuauhehuehuauheuhahue\n-----END RSA PRIVATE KEY-----\n"
If using the key inside an app
e.g. node.
process.env.PRIVATE_KEY
will be outputted correctly.
Solution 7 - Bash
I'll add that a more elegant fool-proof way is to encode the env var as base64 and then decode it when you access it.
const base64 = process.env.GITHUB_PRIVATE_KEY
const privateKey = Buffer.from(base64, 'base64')