SSH key file formats

File: key-formats.txt/md/pdf

You may work in groups of size 1-3 for this assignment.

Goals

Rubric

0 - [but do it anyway!] author name(s) in comment at top of key-formats.txt 6 - contents and meaning of the private key file 3 - contents and meaning of the public key file 2 - sanity check of the relationships between the private and public key

Background

When we first talk about public-key encryption and key exchange protocols, we talk in abstract mathematical terms. For RSA, for example, we talk about prime integers p and q, least common multiples, modular exponentiation, etc. But if you want to use these mathematical ideas in a practical encryption system, you need to deal with concrete questions like "how are we going to store private and public keys?"

In this assignment, you're going to look at the various standards specifications that are used to store keys for use in the SSH protocol.

Do a little reading first

Your job

In your key-formats.* file, include the following.

  1. Create an RSA public/private key pair that you will use throughout the rest of this assignment.

    ssh-keygen -t rsa -m pem

    When you are asked to pick a file name, use "id_rsa_homework" so you can remember to delete these files when you're done with the assignment. (You're going to be posting your observations in a public GitHub repo, so you're not going to ever actually use this key pair for anything.)

    Copy the contents of id_rsa_homework and id_rsa_homework.pub into your key-formats.* file.

  2. Put a heading in your report: "Private Key"

  3. For your private key file (id_rsa_homework), list the items you expect to be contained in the file. (Hint: the Appendix of RFC 8017 should help.)

  4. Use one or more of the following tools (findable by searching the internet for "web asn.1 decoder") to decode your private key file.

    Explain briefly the steps you took to decode the private key file.

  5. For each integer in your decoded private key file, tell me:

    • What is the meaning/name of the integer? This should correspond to one of the items in your answer to the previous question, articulated as an ASN.1 name from the specification in RFC 8017.
    • What is the value of the integer? Write the integer in either decimal or hexadecimal, whichever is more convenient. If hexadecimal, prepend the integer with "0x".
  6. Next, we're moving on to the public key file id_rsa_homework.pub, so put a heading in your report: "Public Key"

  7. Do the same things you did for the private key: write down what you expect to find in id_rsa_homework.pub and why; explain how you decoded the file; for each integer in the file, provide its name, value, and any other relevant details. Unlike with the private key, I'm not telling you exactly where to look in the specifications to figure out this key's file format. (Though you might find this blog post by Leonardo Giordano handy. Aren't I nice?)

  8. Put one last heading in your report: "Sanity check"

  9. Demonstrate that the integers you found in these two files work as you expect from an RSA key pair. For example, does e*d mod lambda(n) = 1? There are various relationships that you would expect these numbers to have, so show me that they do in fact have those relationships.

Late-breaking advice

Let me try to clarify some of what's going on with the public key file.

First, the ssh-keygen command is part of a larger software package called OpenSSH. The OpenSSH people, in their wisdom, designed some file formats that are different from the private-key format you're looking at in this assignment. That's why if you leave out the -m pem part of the command shown above, you'll get an OpenSSH-specific private-key file format, which is not what I wanted you to study for this assignment.

But it turns out that even if you use the -m pem flag, the public key file you get is in an OpenSSH-specific format. That's cool, but it makes dealing with this public key a little harder than the private key for this assignment.

Choice #1: convert your id_rsa.pub file to PKCS#1 PEM form

I'm assuming your public key file is named id_rsa.pub. You can convert it from OpenSSH form to the more generic PKCS#1 PEM file format like so:

ssh-keygen -f id_rsa.pub -e -m pem > id_rsa.pub.pem

The Michael Holtstrom decoder linked above can handle this, but now that I say that, it turns out he has a 2022 note at the top of his page that says he has a newer, better version of his decoder, and he's absolutely right. So you can paste your id_rsa.pub.pem file into this newer decoder and get the decoded version of the RSAPublicKey object in question.

Choice #2: work directly with the OpenSSH public key

Roughly, I did this:

I'm happy with either choice. I hope this helps.