Skip to content

Commit

Permalink
updated how to verify file signagures with rekor
Browse files Browse the repository at this point in the history
  • Loading branch information
erikaheidi committed Dec 12, 2024
1 parent 7a74d78 commit 809c760
Showing 1 changed file with 74 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ type: "article"
description: "Use Rekor or curl to verify non-container software artifacts"
lead: "Rekor or curl can verify software artifacts beyond containers"
date: 2022-12-21T15:22:20+01:00
lastmod: 2022-12-21T15:22:20+01:00
lastmod: 2024-12-12T15:22:20+01:00
draft: false
tags: ["Rekor", "Procedural"]
images: []
Expand All @@ -15,124 +15,156 @@ weight: 005
toc: true
---

The `rekor-cli` tool or `curl` can be used to verify anything with a signature on a [Rekor transparency log](/open-source/sigstore/rekor/an-introduction-to-rekor/#transparency-log). This tutorial assumes you have the `rekor-cli` tool installed, which you can achieve by following our [How to Install the Rekor CLI](/open-source/sigstore/rekor/how-to-install-rekor/) guide. When verifying a signature using either tool, ensure that you have the `jq` utility installed so that you can parse their output.

We’ll verify a binary artifact, in this case, a copy of [apko](/open-source/apko/overview/), which is a tool for building container images using a declarative language based on YAML. The methods in this tutorial apply to any blob file that Cosign has signed with a keyless signature.
You can use the `rekor-cli` tool to verify signatures of artifacts other than container images. For example, you can verify the signature of a binary file that has been signed using a keyless signature as part of their release process. By querying the [Rekor transparency log](/open-source/sigstore/rekor/an-introduction-to-rekor/#transparency-log), you can verify that the binary file you downloaded matches the one that was signed using Cosign. If you prefer, you can also query the Rekor API directly using `curl`.

### Verifying a binary with rekor-cli
In this tutorial, we'll demonstrate how to verify a binary file using `rekor-cli` and `curl`. We'll use [apko](/open-source/apko/overview/) as an example, since all its releases are signed with Cosign. The methods in this tutorial apply to any blob file that Cosign has signed with a keyless signature.

All apko releases are released with [keyless signatures using Cosign](/open-source/sigstore/cosign/an-introduction-to-cosign/#keyless-signing). You can verify the signature for an apko release by searching for the SHA256 hash of the release and finding the corresponding Rekor transparency log entry.
## Preparation
To follow up with all commands in this tutorial, you need to have `curl` and the `rekor-cli` tool installed. You can install it by following our [How to Install the Rekor CLI](/open-source/sigstore/rekor/how-to-install-rekor/) guide. You also need to have the `jq` utility installed to parse the output of `rekor-cli` and `curl`.

We'll use the `apko_0.6.0_linux_arm64.tar.gz` tar archive from the apko [GitHub Release v0.6.0 page](https://github.com/chainguard-dev/apko/releases/tag/v0.6.0) in this example.

First, download the file using curl or your browser:
### Download the Example File
We'll use the `apko_0.20.1_linux_amd64.tar.gz` tar archive from the apko [GitHub Release v0.20.1 page](https://github.com/chainguard-dev/apko/releases/tag/v0.20.1) for the examples in this tutorial. You can download the file using `curl` or your browser:

```sh
curl -L -O https://github.com/chainguard-dev/apko/releases/download/v0.6.0/apko_0.6.0_linux_amd64.tar.gz
curl -L -O https://github.com/chainguard-dev/apko/releases/download/v0.20.1/apko_0.20.1_linux_amd64.tar.gz
```

Then, set up a shell variable to store the SHA256 hash of the `apko_0.20.1_linux_amd64.tar.gz` release file:

```sh
SHASUM=$(shasum -a 256 apko_0.20.1_linux_amd64.tar.gz |awk '{print $1}')
```




To search Rekor, set a shell variable to the SHA256 hash of the `apko_0.6.0_linux_amd64.tar.gz` release file:
You can verify that the variable has been set correctly by running:

```sh
SHASUM=$(shasum -a 256 apko_0.6.0_linux_amd64.tar.gz |awk '{print $1}')
echo $SHASUM
```

If you are using the `rekor-cli` client, search for the hash with the following command:
You should get output similar to this:

```sh
rekor-cli search --sha "${SHASUM?}"
```shell
442d8baafc0c3a873b21a3add32f5c65f538fb5cbcf4a4a69ba098a2b730c5d2
```

If you are using `curl`, run the following:
With this environment variable set up, you can proceed to the rest of this guide.

## Verifying a Binary with `rekor-cli`

We'll now use the `rekor-cli` tool to verify the signature of the `apko_0.20.1_linux_amd64.tar.gz` binary file. First, we'll search the Rekor log for the hash of the binary file. Then, we'll retrieve the Rekor log entry for the hash and extract the signature and public key to verify the binary file.

To search for the hash in the Rekor log using `rekor-cli`, run the following command:

```sh
curl -X POST -H "Content-type: application/json" 'https://rekor.sigstore.dev/api/v1/index/retrieve' --data-raw "{\"hash\":\"sha256:$SHASUM\"}"
rekor-cli search --sha "${SHASUM?}"
```

You will receive output like the following:

```
# rekor-cli output
Found matching entries (listed by UUID):
24296fb24b8ad77a9ec23abb6326ebbaa6932f720847080e8f5e0b2925a1643b63962691917c8137
# curl output
["24296fb24b8ad77a9ec23abb6326ebbaa6932f720847080e8f5e0b2925a1643b63962691917c8137"]
```

Set a shell variable called `UUID` to the returned entry:

```sh
UUID="24296fb24b8ad77a9ec23abb6326ebbaa6932f720847080e8f5e0b2925a1643b63962691917c8137"
UUID="108e9186e8c5677a8d6736bdd79170adf94bd127aea751274d1d62504e88b058af7552d91dea0f26"
```

Now you can use the returned UUID to retrieve the associated Rekor log entry. If you are using `rekor-cli` run the following:
Now you can use the returned UUID to retrieve the associated Rekor log entry:

```sh
rekor-cli get --uuid "${UUID?}"
```

If you are using `curl` then run this command:
This will return a long payload that you can parse using `jq` in order to extract the relevant fields. You can skip to the [Fetching a Signature and Public Certificate](#fetching-a-signature-and-public-certificate) section to learn how to verify your binary matches what is in the Rekor log.

## Verifying a Binary with `curl`
To query the Rekor API directly for the hash using `curl`, you'll need to make a POST request to the `https://rekor.sigstore.dev/api/v1/index/retrieve` endpoint, passing along the hash as a JSON payload. You can then use the returned UUID to retrieve the associated Rekor log entry.

Run the following command to query the Rekor API for the hash:

```sh
curl -X POST -H "Content-type: application/json" 'https://rekor.sigstore.dev/api/v1/index/retrieve' --data-raw "{\"hash\":\"sha256:$SHASUM\"}"
```
You will get output like this:

```shell
["108e9186e8c5677a8d6736bdd79170adf94bd127aea751274d1d62504e88b058af7552d91dea0f26"]
```

Next, set a shell variable called `UUID` to the returned entry:

```sh
UUID="108e9186e8c5677a8d6736bdd79170adf94bd127aea751274d1d62504e88b058af7552d91dea0f26"
```

Now you can use the returned UUID to retrieve the associated Rekor log entry:

```sh
curl -X GET "https://rekor.sigstore.dev/api/v1/log/entries/${UUID?}"
```

In both cases, if you would like to extract the signature and public key to verify your binary matches what is in the Rekor log, you will need to parse the output. You will need to use tools like `base64` to decode the data, `jq` to extract the relevant fields, and `openssl` to verify the signature.
This will return a long payload that you can parse using `jq` in order to extract the relevant fields. To verify the signature and decode the data, you'll also need `base64` and `openssl`.

## Fetching a Signature and Public Certificate

##### Fetch a signature and public certificate using `rekor-cli`
If you would like to extract the signature and public key to verify your binary matches what is in the Rekor log, you will need to parse the output. You will need to use tools like `base64` to decode the data, `jq` to extract the relevant fields, and `openssl` to verify the signature.

### If you're using `rekor-cli`

The following commands will fetch the Rekor entry for a release using `rekor-cli`, parse and extract the signature and public certificate using `jq`, and decode it using `base64`:

```sh
rekor-cli get --uuid "${UUID?}" --format json \
| jq -r '.Body .HashedRekordObj .signature .content' \
| base64 -d > apko_0.6.0_linux_amd64.tar.gz.sig
| base64 -d > apko_0.20.1_linux_amd64.tar.gz.sig
```
```shell
rekor-cli get --uuid "${UUID?}" --format json \
| jq -r '.Body .HashedRekordObj .signature .publicKey .content' \
| base64 -d > apko_0.6.0_linux_amd64.tar.gz.crt
| base64 -d > apko_0.20.1_linux_amd64.tar.gz.crt
```

##### Fetch a signature and public certificate using `curl`
### If you're using `curl`

The following commands will fetch the Rekor entry for a release using `curl`, parse and extract the signature and public certificate using `jq`, and decode it using `base64`:

```sh
curl -s -X GET "https://rekor.sigstore.dev/api/v1/log/entries/${UUID?}" \
| jq -r '.[] | .body' \
| base64 -d |jq -r '.spec .signature .content' \
| base64 -d > apko_0.6.0_linux_amd64.tar.gz.sig
| base64 -d > apko_0.20.1_linux_amd64.tar.gz.sig
```

```shell
curl -s -X GET "https://rekor.sigstore.dev/api/v1/log/entries/${UUID?}" \
| jq -r '.[] | .body' \
| base64 -d |jq -r '.spec .signature .publicKey .content' \
| base64 -d > apko_0.6.0_linux_amd64.tar.gz.crt
| base64 -d > apko_0.20.1_linux_amd64.tar.gz.crt
```

##### Verifying a signature using `openssl`
## Verifying a signature using `openssl`

Now that you have downloaded the signature and public certificate corresponding to your `chainctl` version, you can verify the binary's signature using `openssl`.
After running both commands from the previous section and whether you used `rekor-cli` or `curl`, you should have two new files in your current directory: `apko_0.20.1_linux_amd64.tar.gz.sig` and `apko_0.20.1_linux_amd64.tar.gz.crt`. These are the signature and public certificate files for the apko release, respectively. We can now use `openssl` to verify the binary file against the signature.

First, extract the public key portion of the `apko_0.6.0_linux_amd64.tar.gz.crt` certificate file:
First, extract the public key portion of the `apko_0.20.1_linux_amd64.tar.gz.crt` certificate file:

```sh
openssl x509 -in apko_0.6.0_linux_amd64.tar.gz.crt -noout -pubkey > apko_0.6.0_linux_amd64.tar.gz.pubkey.crt
openssl x509 -in apko_0.20.1_linux_amd64.tar.gz.crt -noout -pubkey > apko_0.20.1_linux_amd64.tar.gz.pubkey.crt
```

Now you can use `openssl` to verify the signature against your local `chainctl` binary. Run the following command:
Now you can use `openssl` to verify the signature against your local apko binary. Run the following command:

```sh
openssl sha256 -verify apko_0.6.0_linux_amd64.tar.gz.pubkey.crt -signature apko_0.6.0_linux_amd64.tar.gz.sig apko_0.6.0_linux_amd64.tar.gz
openssl sha256 -verify apko_0.20.1_linux_amd64.tar.gz.pubkey.crt -signature apko_0.20.1_linux_amd64.tar.gz.sig apko_0.20.1_linux_amd64.tar.gz
```

If your `apko_0.6.0_linux_amd64.tar.gz` download matches the one that was signed using Cosign, you will receive the following line of output:
If your `apko_0.20.1_linux_amd64.tar.gz` download matches the one that was signed using Cosign, you will receive the following line of output:

```
Verified OK
```

This output indicates that your `apko_0.6.0_linux_amd64.tar.gz` version is authentic and was signed by the ephemeral private key corresponding to the public certificate that you retrieved from the Rekor log.
This output indicates that your `apko_0.20.1_linux_amd64.tar.gz` version is authentic and was signed by the ephemeral private key corresponding to the public certificate that you retrieved from the Rekor log.

0 comments on commit 809c760

Please sign in to comment.