101

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: text 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: How to set multiline RSA private key environment variable for AWS Elastic Beans

image

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$//')"

image 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"...)

frederj
  • 1,483
  • 9
  • 20
nelsonic
  • 31,111
  • 21
  • 89
  • 120
  • 2
    Your .sh script had a problem: you were trying to `export $var` (by reference/value) but should `export var` (by name) instead. Anyway, the answer is simple: `bash` allows multiline string literals, as long as they are quoted. Use either single or double quotes. – MarkHu Feb 13 '19 at 16:46
  • @MarkHu Your approach is not working. – SFin Jun 25 '19 at 08:36
  • Unless I misunderstand what I'm looking at, you've published a private key on Stack Overflow for the world to see. It's been a year, but if this key is still active, you should change it. – rp.beltran Nov 16 '19 at 01:30
  • @rp.beltran the key is not long enough to be a valid RSA private key. but thanks for your concern. :-) – nelsonic Nov 18 '19 at 09:57
  • 1
    Good point, my bad – rp.beltran Nov 18 '19 at 10:50

6 Answers6

116

export the key

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

test.sh

#!/bin/bash

echo "$PRIVATE_KEY"; 

Note: the " in the echo above are needed - otherwise the new lines will be converted to spaces!

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.

Greg Dubicki
  • 5,983
  • 3
  • 55
  • 68
Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
  • 6
    As noted in this answer, https://stackoverflow.com/a/53271334/292408, the `echo $PRIVATE_KEY` sometimes strips all the newlines when showing output. I think it depends on the shell of maybe version or echo. But the example would be better & more accurate if wrapped with double quotes. – Elijah Lynn Feb 15 '19 at 01:41
  • 1
    Also of note that I just realized, `env` always shows the variables correctly, with newlines. – Elijah Lynn Feb 15 '19 at 01:42
  • when i try access my key from .env file its only returning the first line '-----BEGIN RSA PRIVATE KEY-----' – Marcelo Fonseca May 23 '20 at 19:33
  • I m only getting last line of the key file in this case – Aman Prakash Jun 04 '20 at 20:00
  • 1
    I'm using a .env file with a project in Glitch, and wrapping the key in single quotes was the only solution that worked for me...I had been searching for awhile so thanks!! – Tristan Bennett Sep 17 '20 at 15:11
  • Evaluating a variable in .env ins not an option for most applications. Imagine an encrypted private keys in Kubernetes service for example. As proposed in the end of this thread: https://github.com/dwyl/learn-environment-variables/issues/17 the best option is to encode the key with a base64 and decode it when accessing it. – Paperclip Feb 03 '22 at 10:10
42

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-----"
Amio.io
  • 20,677
  • 15
  • 82
  • 117
  • 2
    I have tried the same but instead of reading the full key it is reading it as ```"-----BEGIN RSA PRIVATE KEY-----``` – Wasif Ali Aug 30 '21 at 11:34
  • @WasifAli Did u really put `"` after `-----END RSA PRIVATE KEY-----`? – Amio.io Sep 06 '21 at 16:29
  • 2
    Yes I have tried this, it didn't work, so what worked for me was to replace all the new lines with '\n' characters. – Wasif Ali Sep 07 '21 at 12:29
26

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"
Brett Beatty
  • 5,690
  • 1
  • 23
  • 37
  • 4
    DAMN!!! This is great, I kept checking a variable without the quotes and kept getting 1 line (`echo $TEST | wc --lines`). And was going crazy!!! Thanks for suggesting this, very helpful in determining it actually did have all the lines. – Elijah Lynn Feb 15 '19 at 01:39
  • 2
    Also of note that I just realized, `env` always shows the variables correctly, with newlines. – Elijah Lynn Feb 15 '19 at 01:42
17

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 smeagol@192.143.69.69

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.

daparic
  • 3,794
  • 2
  • 36
  • 38
8

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.

Marcelo Fonseca
  • 1,705
  • 2
  • 19
  • 38
7

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')
Carter
  • 1,184
  • 11
  • 5