The 1024 Club Part 2 - Why Are Signatures So Damn Difficult? (published 2020-05-04)

This is part 2 of a series on design decisions I've made in my proposal for how The 1024 Club should work.

The next step is making signatures work. The entire model of authority, when it comes to the1024.club, depends on being able to verify a signature of the kilobyte of data. In a perfect world, I'd be able to import a package, and call a function with the pubkey, data and signature, which would then return True if the signature matched and False otherwise.

If only it were that easy.

As it turns out, no such function exists, at least not anywhere I could find it. Looks like I'll have to do it my own damn self.

The good news is that there is a cryptography library for Python already. The bad news is that the parts I need (RSA public keys, verifying a signature) are underdocumented, since you aren't supposed to use them unless you already know what you're doing.

I decide to start with RSA keys. I write a simple wrapper around an example on the documentation page for RSA keys, and, after finaggling the difference between using type and using isinstance, I have a function that, in theory, should be able to Just Work(TM) if I supply the info. I use OpenSSL to generate a signature for a test file, call the function with the public key, data, and signature...

...and it fails. Well, shit.

After 3 hours of finaggling sparse documentation (during which I kept myself sane by writing a parody of the Buffalo Bills fight song (titled "Crypto makes me wanna DIE!") and a parody of "I'll Fly Away" where I changed the lyrics to be about crypto being confusing (although eventually the lyrics devolved into screaming)), I figure out that the reason it's failing is because OpenSSL and the cryptography library have differing opinions on what the maximum salt length of PSS padding is. ...What?

I bypass this issue by making both of them use a salt length of 32 (which is the recommended length, since I'm using SHA-256, which returns a hex digest of 32 characters), and... it works!

Needless to say, I left off with only implementing RSA public keys, because that was so much of a pain I don't even want to think about crypto for a week.

The next thing to do is to write the actual server that will handle the real requests. That should be fun. (In case that wasn't clear, I'm being sarcastic.)