Using private key in a .env file
Asked Answered
H

9

49

I have a multiline private key in a gatsby .env file:

GATSBY_GOOGLE_CLIENT_ID="12345"
GATSBY_GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nflkdflkdf...\n-----END PRIVATE KEY-----"

In my gatsby-config file I have:

module.exports = {
    resolve: 'gatsby-source-google-sheets',
    options: {
        credentials: {
            "type": "service_account",
            "private_key": process.env.GATSBY_GOOGLE_PRIVATE_KEY,
            "client_id": process.env.GATSBY_GOOGLE_CLIENT_ID
        }
    }
}

The client_id works fine because it's just a one line string but the private_key doesn't work, presumably because it's multi line.

Is there a way I can get around this?

Thanks

Hardej answered 1/4, 2019 at 16:19 Comment(1)
Looks like there was an extra { and missing , in the code above. I've corrected these, but I'm not sure if the same mistake is in your original version?Vocational
V
66

You could use string.replace with a regular expression as below to escape the \n characters again:

"private_key": process.env.GATSBY_GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n'),
Vocational answered 1/4, 2019 at 16:33 Comment(7)
I get: Cannot read property 'replace' of undefined: const private_key = process.env.GATSBY_GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n'); module.exports = {...} Something to do with the const being declared outside module.exports maybe?Hardej
Sounds like it was out of scope where you added the line - I've updated to match your question more closely.Vocational
Same error unfortunately. Don't seem to be able to use .replace on process.envHardej
Weird - it worked for me. Can you check using a debugger that GATSBY_GOOGLE_PRIVATE_KEY definitely has a string assigned to it?Vocational
I don't know how, but this solution works. Would love if someone could explain this in layman terms as well :)Paleozoology
The replace function is searching for all occurrences of the literal string \n (which to avoid being escaped is defined as "\\n") and replacing with the newline character: \n, Unicode : U+000A, ASCII : 10, hex : 0x0a. To ensure that all occurrences are replaced, the /......../g regex expression is used. This question gives a clear explanation #39031719.Vocational
I use .replace('\\n', '\n') in python and it works like a charm in combination with lambda envPsychopharmacology
B
53

Solution which worked for me -- Encoding the Private Key in base 64

Step1 - Convert Key to Base 64

// Run this code in a JS file on your Dev Machine.
const privateKey= `-----BEGIN PRIVATE KEY-----\nMIIEvSomeMoreCharacterHererplw==\n-----END PRIVATE KEY-----\n`
const buff = Buffer.from(privateKey).toString('base64');
console.log(buff);

Note: You don't need to commit/include the above code in your project. This is just to generate the base64 string of the key.

Step 2 - Copy the console log data to .env file

PRIVATE_KEY = 'akgjhakdgjhasgf'

Step 3 - Using the Key in the code

const key = Buffer.from(process.env.PRIVATE_KEY , 'base64').toString('ascii');
// Use key anywhere in your code.
Beni answered 10/8, 2021 at 16:42 Comment(6)
why ascii and not utf8 when decoding?Braque
Need to make sure there isn't \n in the end of the key (as in the example) to get it workingDough
For anybody reading in the future, this answer is better than the accepted answerPoachy
Yes, this is indeed the better solution than messing around with regular expressionsKleist
Note for future myself) 1. The Buffer.from overload takes an encoding method as a second parameter optionally, which defaults to 'utf8'; what Buffer.from and Buffer.toString do is encoding/decoding between binary(bytes) and string. 2. Presumably OP is dealing with a ".pem" file (PEM format) since there is a header and a footer such as "-----BEGIN PRIVATE KEY-----..."; PEM format uses base64 as an encoding/decoding method. 3. So... this answer is not a very canonical way but doing a "trick".July
I also agree, this should be the accepted answer.Dedans
H
19
  1. Copy your content from your pem file to the browser's console (add ``):
`-----BEGIN RSA PRIVATE KEY-----
loremipsum...
-----END RSA PRIVATE KEY-----`
  1. Copy the log from the browser (notice \ns were added)
  2. Add it to your env file (notice the ""):
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nloremipsum...\n-----END RSA PRIVATE KEY-----"
Homestretch answered 30/11, 2022 at 7:47 Comment(2)
look no further, googling developer! this is the right answer :)Bregenz
ilysm, there must be soo many private keys stackoverflow has access to in the console.log of this pagePolyp
B
17

I'm adding a manual approach that worked for me. 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 the value process.env.PRIVATE_KEY in your code will only show the first line: -----BEGIN RSA PRIVATE KEY-----\n. To fix this, edit the variable in .env to a single line. Like this:

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

Now process.env.PRIVATE_KEY will be outputted correctly.

Brahma answered 23/5, 2020 at 20:39 Comment(2)
I'm able to read the private key and export it to the env file. But I don't understand what step 2 is about. Can you explain?Lavena
@yogescicak edit the value to stay in one line.Brahma
G
7

I have similar issues where i have to read .pem file content. The following approach worked for me.

  • Convert the .pem content into base64 format
  • Put converted base64 content (this will be single line string) in .env file
  • Now decode env variable into original content
Gaul answered 1/4, 2021 at 7:22 Comment(1)
cat <file.pem> | openssl base64 | tr -d '\n'Dike
H
4

Turns out the path to my .env was incorrect. For some reason the other keys were working but the private key was not.

The correct setup:

require("dotenv").config({
    path: `./.env.${process.env.NODE_ENV}`,
});
const private_key = process.env.GATSBY_GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n');

module.exports = {
    resolve: 'gatsby-source-google-sheets',
    options: {
        credentials: {
            "private_key": private_key,
        }
    }
}

Hardej answered 2/4, 2019 at 10:22 Comment(1)
So did the Private key work as formatted above once you'd changed the path?Crocked
W
1

You'd have to load the env variables into gatsby. The simplest way is to use dotenv:

Setup:

yarn add -D dotenv # or npm install -D dotenv

Then in your gatsby-config.js:

require('dotenv').config();

module.exports = {
  plugins: [ ... ]
}

If your file name is different than .env or you store it in different location, you can pass in a path option:

require('dotenv').config({
  path: 'path/to/env/file'
});
Wootan answered 2/4, 2019 at 3:16 Comment(1)
Thank you! I actually already had that in but the path was wrong. I'm not sure why the others were working and that wasn't but fixing the path has sorted the issue.Hardej
D
0

Put in in a pem file and then right it to your .env with replacements

echo "export test_key=\"`sed -E 's/$/\\\n/g' ./gitbu.2018-03-23.private-key.pem`\"" >> .env
Debussy answered 1/4, 2019 at 16:40 Comment(0)
T
0

I just remove ";" from the end of private key in .env file and it worked for me...I know it would seems dumb for some but many made this mistake as they are too used to with Javascript and solidity...

Tadashi answered 16/11, 2022 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.