I'm writing some unit and integration tests around JWT creation and validation. I'm hacking together a quick JWKS page using real (well self-signed) certs I created with openssl, and I was cooking along until I got to this very simple problem:
The "E" value is 65537, but in the JWKS it is suppose to be AQAB. After beating my head on the wall for a very long time, I finally figured it out on paper.
https://www.rfc-editor.org/rfc/rfc7518#section-6.3.1.2
65537 is 0000 0001: 0000 0000 : 0000 0001
If you shift that to 6 bits for base64 you get
000000 010000 000000 000001
Which is A Q A B
https://en.wikipedia.org/wiki/Base64#Base64_table
So I tried to whip up some quick code. but it proved very not-quick. I was thinking, there MUST be an easier way. All the base64 encoding I tried, gave me way more than 3 bytes.
So did what any self respecting coder would do... I saw that everybody uses 65537, so I hard coded that sucker and moved on, but it just keeps nagging at me. I hate problems that vex me.
The closest that I got was:
bs := make([]byte, 4)
binary.BigEndian.PutUint32(bs, 65537)
fmt.Println(bs)
fmt.Println(base64.URLEncoding.EncodeToString(bs))
Which produced:
[0 1 0 1]
AAEAAQ==
which my quick math said, that base64 output is why more than 3 bytes :D