Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- GitHub Community Forum
- :
- Conversations
- :
- GitHub Actions
- :
- [API] Encrypting a secret using the public key and...

Options

- Subscribe to RSS feed
- Mark all as new
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer friendly page

Copilot Lvl 2

02-15-2020
02:01 PM

- Mark as new
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Message 1 of 3

Solved! Go to Solution.

I am trying to add a "secret" via the API.

I am using the sodium R package which provides support for libsodium.

Below I outline my approach where "pub_key_gh" is the character value representing the public key mentioned in the API docs.

1. Serialize the private key which should be encrypted

2. Decode the public key from Github

3. Encrypt the serialized private key using the public key

4. Encode the encrypted private key again because only base64 encoded strings can be pushed via the API

private_key = sodium::hash(charToRaw(private_key)) pub_key_gh_dec = base64enc::base64decode(pub_key_gh) private_key_encr = sodium::simple_encrypt(private_key, pub_key_gh_dec) private_key_encr = base64enc::base64encode(private_key_encr)

However, during the Action run the private key is marked as "invalid format". Hence, most likely the pushed secret was not decoded correctly behind the scenes when being inserted in the run / was uploaded in the wrong format.

Any help is appreciated - I am newbie when it comes to encryption so I can very well be that one of the steps outlined above does not make sense / is not needed.

Manually adding the "private key" via the Github web interface works without problems so its really about how to encrypt the key correctly / upload it in the right format.

Solved! Solved! Go to Solution.

2 Replies

Highlighted
##

Pilot Lvl 1

02-16-2020
03:49 AM

- Mark as new
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Message 2 of 3

Re: [API] Encrypting a secret using the public key and libsodium

Although I am also an encryption-noob (who isn't?), I just recently created a CLI that pushes secrets to GitHub using the API, so the information is fresh in my mind.

I didn't see nor use any private key in the process.

The same documentation page you referenced has examples in several languages (not R unfortunately) further down the page.

In general, the process as described is this (pseudocode):

# API call to get the public key for the repo

base64_encoded_public_key, key_id = get_public_key_from_github(repo_name)

# Base64 decode the key

public_key = base64_decode(base64_encoded_public_key)

# Encrypt the secret with sodium and the public key plain_secret = "secret" encrypted_secret = sodium_encrypt(public_key, plain_secret)

# Base64 encode the encrypted secret base64_encoded_secret = base64_encode(encrypted_secret)

# Send it to GitHub using the API, and including the key_id as received in step 1 push_secret_to_github(key_id, base64_encoded_secret)

And this is the example in Ruby:

key = Base64.decode64("+ZYvJDZMHUfBkJdyq5Zm9SKqeuBQ4sj+6sfjlH4CgG0=") public_key = RbNaCl::PublicKey.new(key) box = RbNaCl::Boxes::Sealed.from_public_key(public_key) encrypted_secret = box.encrypt("my_secret") # Print the base64 encoded secret puts Base64.strict_encode64(encrypted_secret)

In my development, I also tested that I can decrypt it back. For this you will need to use sodium to generate a public/private key pair (instead of the one you receive from GitHub), then follow the encryption steps as above, using the public key, and then decrypt it with the same sodium method, only this time using the private key - to verify the output is decrypting properly.

If it will help, or if you are in need of a way to do it and are not married to doing it in R, I can share a link to my CLI (in Ruby).

Highlighted

Solution

Copilot Lvl 2

02-16-2020
08:34 AM

- Mark as new
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Message 3 of 3

Thanks @DannyBen!

Your post helped, thanks! I got it working now and I think I was already very close yesterday but did some mistakes on the public key side - but I can't really recall.

In the end, my solution looks like this. Here, we assume that the Github public key is already available via some external code.

library("sodium") library("base64enc") # convert to raw for sodium msg = "message" msg_raw <- charToRaw(msg) # decode public key pub_key_gh_dec <- base64enc::base64decode(pub_key_gh) # encrypt using the pub key msg_raw_encr <- sodium::simple_encrypt(msg_raw, pub_key_gh_dec) # base64 encode secret msg_raw_encr_enc <- base64enc::base64encode(msg_raw_encr)

New solutions

Top Kudoed Posts