Using WebCrypto API to generate a KeyPair

The other day, I was using my chromebook and I needed to generate a keypair to get access to a new ssh server. I googled for a solution, but surprisingly I couldn't find one. Though I was pretty sure that the WebCrypto API would allow me to do easily, it turned out it's not as easy as I thought and it took me a couple days to actually figure out how to use the webcrypto API to achieve this specific goal, though this was mostly due to my blissful ignorance of ASN.1 encoding, JWK, base64url and openssh weird public key format.

Of course the first point of reference should be the the actual W3C spec. But this document is a bit too abstract and I found it hard to actually use the API from the spec.

Then I found a WebCrypto live table that tells me if my current browser actually support the API. Since some of those use native libraries, the Chrome on ChromeOS would have different support as the Chrome on other OSes.

We also need to keep in mind that the WebCrypto api is only available from secure locations. Luckily the file url is counted as a secure location, so it makes it easy to experiment from there. And surge.sh does host under https so that will be my provider of choice to host the end result.

On an OS with support for openssh we have the nifty utility ssh-keygen which allows to generate a keypair that can be used with ssh - which is exactly what we need.

So we have to figure out which algorithm to use, then use it with the appropriate parameters, then find a way to expose the public key and the private key. Ideally save the private key to a file and copy the public key.

The WebCrypto api is based on promises for the async work, so you will need to be vaguely familiar with promises to be able to read the code.

I am forever grateful to Converting OpenSSH public Keys for explaining the format used by OpenSSH public keys.

I also had to use a lot of google-fu to find out how to ASN.1 encode the JWK produced for the private key by the WebCrypto API in format that will be accepted by openSSH. Thanks to Lapo Luchini for putting together the awesome ASN.1 online decoder that allowed me debug my code and find out that ASN.1 doesn't like integer that starts with the high bit set (you have to prefix them with 0x00 in this case).

Please note that it is usually a very bad idea to put private keys in a browser, as most thing that are displayed on a web page can be stolen and a private key is probably the worst thing you could think putting on a web page.

But now, equipped with those two string representation of my key pair, I can setup my ssh connection straight from my Chromebook without having to use another OS. I am using the ssh chrome extension.

Live demo at https://js-keygen.surge.sh
Code at https://github.com/PatrickRoumanoff/js-keygen


My Weekend

At my previous job, we used to have an informal Monday morning catchup where everyone would talk about their week-end activities before going on about their planned work activities for the week.
When I left, quite a few people told they were always looking for my updates to spin their heads about how many km I had to do to drop how many kids where...
So here is an account on my week-end.

It started on Friday afternoon, when we got ready to go to Friday night races organised by Carlisle Swimming center, as four of the kids are in the right groups to register for the races, it's only $12 per family so it's a great deal for us. And it's a lot of fun, you can win medals and get special cards if you get into the first three or achieve a personal best. J2 likes to do the long distance races, 100m freestyle or breathstroke, but all the other contestants are twice her size and finish in half the time, but she still manages to enjoy herself, and everyone clap when she get to the end.

Saturday starts pretty early as my wife is teaching the french horn from 7:30 to 12:30. Beside the usual breakfast, J1 made pancake for everyone which was nice. We left at 8:30 to head to choir which starts at 9:00 in the city. While J1 & J2 went to choir, we took a walk in the new Barangaroo park with E2, V and C, which was very nice, but E2 was wearing his brand new choir rehearsal outfit and had a difficult time stopping himself from rolling in the dirt, going down stair ramps and climbing rocks close to the water. The park is very nice and the weather was awesome.
J1 & J2 didn't like me going to the park as I usually do parent supervision at choir instead and they were pretty horrible all the way to the swimming pool.
Swimming was good with 5 of them in the water it's pretty relaxing time for me - which means no one cried to get into the water. It was a big day for E2 because he got evaluated and he managed to up a level - which is a big issue for me because there is no class for "SuperFish" at 10:30 and this breaks all my Saturday schedule. We manage to find a spot at 9:00 but I can only drop him at 8:30 on my way to choir - we will test  that next week.

After swimming it was time to go register for next Friday night races - and J2 decided for the 100m again - she is certainly persistant. Whereas I have to encourage Violette to do more than 25m (since the figured out she can get as many points out of 25m, 50m or 100m she opted for the less tiring option).
Once home  have to remember everyone to hang up their towel & costume - minor drama here as C lost her goggles and swimming cap - we will probably find them next week. You couldn't believe how many goggles we lost  in the 10 years we have been going to swimming lessons - that's why I only get the "3 for $10" deal from Big W, because at $25 a pop for a pair of swimming googles, I would already be ruined.
We also got a phone call V's birthday party was cancelled because the host was sick - which was a relief because there was no one to drive her or pick her up and we didn't get a present...

Lunch was alright - then it was time to go to French class for C - which means doing the homework first, for once J2 helped C which was a nice change. But this time I had to bring E1 and E2 because they have a special choir rehearsal this afternoon, so after dropping off C at french class, it's back to the city for me. Of course, E1 being 13 she has a go at me by not getting out of the car when I told her I was a hurry to get back to French class to pick up C. I know they were tired, because they both dozed off in the car, but still, I got angry at her - I should know better.
Back to French class, C is super happy - which is a nice change - and she can't stop speaking French to me which I love so much. She's actually the only who will voluntarily speak French to me. We go to Aldi for the weekly shopping - we only have one hour because I have to go back to the city at 5:30 to pick up the E1&E2 form Choir. C was super helpful at Aldi and even helped me with the bags at the cashier. Back home to drop the shopping and C and it's off to the city for me (third time in a day).
I arrive 10m late because of traffic, but apparently they finished early so they have been waiting 30m outside - though Steph was here to supervise them.

Saturday adventures finish here.
Then it's Sunday... J1 wants to do crepes for breakfast which is great but 7am is a bit early for a Sunday. We start off with a bassoon lesson at 9:30 for V, but for once my wife is driving, she enjoys that because she can talk a walk on the beach during the lesson, so it's not too bad. At Noon my wife is off to perform in a concert for most of the afternoon so I will be with the kids by myself. Not much planned today, but kids insist on going to Warringah Aquatic Center, which is always fun because I get to argue with the cashier lady on the merit of a family entry when you have 6 kids. Before we get to leave we have to fold the laundry which has been accumulating on the couch for the pat two days, it's always a struggle to get them to fold the laundry, but going swimming is a good motivator. Cashier lady is very strict, and I have to pay for a family ticket + two kids to gain entry. We have lots of fun, and I manage to convince E2 to dive properly, starting from the sitting position, then crouching position, then standing position. I think we managed to overcome his fear of belly flop - at least he now can dive. V found $4 at the bottom of the pool and she buys some hot chips she shares with everyone.
Back home, we have to get ready for cello lesson, luckily the teacher comes home for this one, and she brings her daughter with her. We have a big afternoon tea - cello start for E1 her exam is next Saturday so she has an extra long lesson, then it's J2 and C's turn. During the lesson I start dinner, I bought some prawn and they need to be peeled, no kids want to try, "it's too disgusting" only the cello teacher daughter manages to peel a couple prawns. I cook them with garlic to go with pasta. Kids won't touch them, they can have cheese & tomato sauce. For dessert I make apple crumble, but in the rush I leave the oven on grill instead of fan forced, and it ends up with slightly burned top - still alright to eat but I had done better. Wife is back from concert to share dinner with us, and we even have the cello daughter who is having pasta & apple crumble.

Then it's time for bed - at least for the kids