Encode your secret keys to base64

In this article, I'll show you how to quickly create a script to encode your secret keys to base64, so you can use them for your JWT secret or anything else. Advantages First, let's see why we use this approach: Portability in environments that do not support binary Private keys and certificates may contain binary characters incompatible with certain systems (e.g., environment variables, .env files, YAML, JSON, XML). Base64 encoding turns them into secure ASCII strings compatible with virtually any transmission medium. Storage in environment variables/files Systems like Docker, Kubernetes, CI/CD (GitHub Actions, GitLab CI), and configuration tools (e.g., dotenv) handle text values ​​better. Base64 allows you to store keys/certificates directly as environment variables. PRIVATE_KEY_BASE64=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBL... Secure transmission over HTTP/JSON REST, GraphQL, and gRPC APIs often send data in JSON. Since JSON doesn't support pure binary, Base64 solves this. Example: sending certificates, tokens, images, or files over the network. Avoids issues in your code and line breaks When storing PEMs or private keys directly, line breaks or encoding issues can cause hard-to-diagnose errors. Base64 can be a single line and avoids these issues. Compatible with cryptography and libraries Many cryptography libraries accept Base64 encoded input/output. It's easy to convert back with atob/btoa in the browser or Buffer.from(..., 'base64') in Node.js. Heads up: Base64 is not encryption. It just encodes data – anyone can decode it. Let's get straight to the point We're gonna use OpenSSL to generate the certificates for our keys and then encode them in base64, at the end I'll explain how to decode them using other programming languages. Creating a shell script in your terminal use sudo nano generate-ca.sh or use any text editor of your preference. #!/bin/bash set -e name="certificate" days=365 openssl genpkey -algorithm RSA -out ${name}.key -pkeyopt rsa_keygen_bits:2048 openssl req -new -key ${name}.key -out ${name}.csr -subj "/C=US/ST=NY/L=NYC/O=Company/OU=IT/CN=example.com" openssl x509 -req -in ${name}.csr -signkey ${name}.key -out ${name}.crt -days ${days} cert_b64=$(base64 -w 0 ${name}.crt) echo "$cert_b64" Every line explained: #!/bin/bash Tells the system to use the Bash shell to interpret the script. set -e Instructs the script to exit immediately if any command fails (returns a non-zero status). This prevents the script from continuing after an error. name="certificate" days=365 Defines two variables: name: the base name used for all output files. days: how long the generated certificate should remain valid. openssl genpkey -algorithm RSA -out ${name}.key -pkeyopt rsa_keygen_bits:2048 Generates a 2048-bit RSA private key and saves it as certificate.key. Saves it as certificate.key (because ${name} is "certificate"). openssl req -new -key ${name}.key -out ${name}.csr -subj "/C=US/ST=NY/L=NYC/O=Company/OU=IT/CN=example.com" Creates a Certificate Signing Request (CSR) using the previously generated key. It includes certificate metadata defined in the -subj string: C = Country ST = State L = Locality/City O = Organization OU = Organizational Unit CN = Common Name (usually the domain) openssl x509 -req -in ${name}.csr -signkey ${name}.key -out ${name}.crt -days ${days} Generates a self-signed X.509 certificate using the CSR and private key. It sets the certificate validity to 365 days and saves it as certificate.crt cert_b64=$(base64 -w 0 ${name}.crt) Converts the certificate (certificate.crt) to Base64. -w 0 tells base64 to output it all in one line (no line breaks). The output is stored in the shell variable cert_b64. echo "$cert_b64" Prints the Base64-encoded certificate to the terminal. This is useful for directly copying it into .env files, configuration files, or application source code. the output will be something like this: ....+.........+...+....+.....+.+........+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+......+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.....+.........+.........+.+..+.......+...+..+.+......+........+.+.........+........+...+......+.+........+.......+...+......+.........+.....+.+...+......+..+.........+...+.+...........+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ..+......+.+..+.+..+....+.....+.........+......+.........+.........+...............+...+....+......+..+.+..+.........+...+.......+..............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..........+......+......+.+.....+..........+...+.........+...............+...+..+.+.....+......+...+.............+...+..+....+...+........+...

May 8, 2025 - 06:38
 0
Encode your secret keys to base64

In this article, I'll show you how to quickly create a script to encode your secret keys to base64, so you can use them for your JWT secret or anything else.

Advantages

First, let's see why we use this approach:

Portability in environments that do not support binary

  • Private keys and certificates may contain binary characters incompatible with certain systems (e.g., environment variables, .env files, YAML, JSON, XML).

  • Base64 encoding turns them into secure ASCII strings compatible with virtually any transmission medium.

Storage in environment variables/files

  • Systems like Docker, Kubernetes, CI/CD (GitHub Actions, GitLab CI), and configuration tools (e.g., dotenv) handle text values ​​better.

  • Base64 allows you to store keys/certificates directly as environment variables.

PRIVATE_KEY_BASE64=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBL...

Secure transmission over HTTP/JSON

  • REST, GraphQL, and gRPC APIs often send data in JSON. Since JSON doesn't support pure binary, Base64 solves this.

Example: sending certificates, tokens, images, or files over the network.

Avoids issues in your code and line breaks

  • When storing PEMs or private keys directly, line breaks or encoding issues can cause hard-to-diagnose errors.

  • Base64 can be a single line and avoids these issues.

Compatible with cryptography and libraries

Many cryptography libraries accept Base64 encoded input/output.

It's easy to convert back with atob/btoa in the browser or Buffer.from(..., 'base64') in Node.js.

Heads up: Base64 is not encryption. It just encodes data – anyone can decode it.

Let's get straight to the point

We're gonna use OpenSSL to generate the certificates for our keys and then encode them in base64, at the end I'll explain how to decode them using other programming languages.

Creating a shell script

in your terminal use sudo nano generate-ca.sh or use any text editor of your preference.

#!/bin/bash
set -e

name="certificate"
days=365

openssl genpkey -algorithm RSA -out ${name}.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ${name}.key -out ${name}.csr -subj "/C=US/ST=NY/L=NYC/O=Company/OU=IT/CN=example.com"
openssl x509 -req -in ${name}.csr -signkey ${name}.key -out ${name}.crt -days ${days}

cert_b64=$(base64 -w 0 ${name}.crt)
echo "$cert_b64"

Every line explained:

#!/bin/bash

Tells the system to use the Bash shell to interpret the script.

set -e

Instructs the script to exit immediately if any command fails (returns a non-zero status). This prevents the script from continuing after an error.

name="certificate"
days=365

Defines two variables:

  • name: the base name used for all output files.
  • days: how long the generated certificate should remain valid.
openssl genpkey -algorithm RSA -out ${name}.key -pkeyopt rsa_keygen_bits:2048

Generates a 2048-bit RSA private key and saves it as certificate.key.
Saves it as certificate.key (because ${name} is "certificate").

openssl req -new -key ${name}.key -out ${name}.csr -subj "/C=US/ST=NY/L=NYC/O=Company/OU=IT/CN=example.com"

Creates a Certificate Signing Request (CSR) using the previously generated key. It includes certificate metadata defined in the -subj string:

C = Country
ST = State
L = Locality/City
O = Organization
OU = Organizational Unit
CN = Common Name (usually the domain)

openssl x509 -req -in ${name}.csr -signkey ${name}.key -out ${name}.crt -days ${days}

Generates a self-signed X.509 certificate using the CSR and private key. It sets the certificate validity to 365 days and saves it as certificate.crt

cert_b64=$(base64 -w 0 ${name}.crt)

Converts the certificate (certificate.crt) to Base64.
-w 0 tells base64 to output it all in one line (no line breaks).
The output is stored in the shell variable cert_b64.

echo "$cert_b64"

Prints the Base64-encoded certificate to the terminal.

This is useful for directly copying it into .env files, configuration files, or application source code.

the output will be something like this:

....+.........+...+....+.....+.+........+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+......+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.....+.........+.........+.+..+.......+...+..+.+......+........+.+.........+........+...+......+.+........+.......+...+......+.........+.....+.+...+......+..+.........+...+.+...........+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
..+......+.+..+.+..+....+.....+.........+......+.........+.........+...............+...+....+......+..+.+..+.........+...+.......+..............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..........+......+......+.+.....+..........+...+.........+...............+...+..+.+.....+......+...+.............+...+..+....+...+........+...+............+.........+....+.........+..+......+...+..........+..+..........+...+.....+.+.....+..........+........+...+...+....+..+....+.....+....+..+.+..............+.............+...+.....+...+.+........+...............+...+..........+.....+....+...........+.......+...+..+.+..+.............+.....+.+...+...........+....+..+...+.+.....+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Certificate request self-signature ok
subject=C = US, ST = NY, L = NYC, O = Company, OU = IT, CN = example.com
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQWlrQ0ZEODFOZ0JyMDlob0FWa3d...

where the base64 string you need is:

LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQWlrQ0ZEODFOZ0JyMDlob0FWa3d...

Decode it

PHP

$base64 = "BASE64_STRING_HERE";
$decoded = base64_decode($base64);
file_put_contents("certificate.crt", $decoded);

Node

const fs = require('fs');

const base64 = "BASE64_STRING_HERE";
const buffer = Buffer.from(base64, 'base64').toString('utf-8');
console.log(buffer);

Java

import java.nio.file.*;
import java.util.Base64;

public class DecodeCert {
    public static void main(String[] args) throws Exception {
        String base64 = "BASE64_STRING_HERE";
        byte[] decoded = Base64.getDecoder().decode(base64);
        Files.write(Paths.get("certificate.crt"), decoded);
    }
}

Python

import base64

base64_str = "BASE64_STRING_HERE"
with open("certificate.crt", "wb") as f:
    f.write(base64.b64decode(base64_str))

Go

package main

import (
    "encoding/base64"
    "os"
)

func main() {
    base64Str := "BASE64_STRING_HERE"
    decoded, err := base64.StdEncoding.DecodeString(base64Str)
    if err != nil {
        panic(err)
    }
    os.WriteFile("certificate.crt", decoded, 0644)
}

Elixir

base64 = "BASE64_STRING_HERE"
decoded = Base.decode64!(base64)
File.write!("certificate.crt", decoded)