Generating a DER-encoded DSA public key of a particular file size
Alberto last edited by
I am reverse engineering a binary that contains a raw, DER-encoded X.509 certificate containing a DSA public key. I want to replace this certificate with one that I have generated so that I have access to the private key.
Due to this certificate being inside the binary, I need to replace it with a certificate of the same size in bytes, so that offsets of other data within the file are unharmed.
When I generate my own key-pair using OpenSSL, or Python, or any other method, and I export it, it is close to the file size I need, but not quite. This is just due to the random nature of generating a DSA key.
Is there an easy way to do this, besides picking my own numbers and manually performing the math necessary to generate the DSA keys? It doesn't need to be secure, this is just a fun little experiment.
There are lots of things in an X.509 certificate other than the publickey whose sizes can be varied to pretty much anything you want, especially if you don't care about security: all the name fields, CRLDP, AIA, Policy, maybe more.
For the DSA publickey in the cert (assuming 'normal' format not implicitlyCA which practically no one used) P and Q will always be the same sizes, each with one 'extra' octet in DER over the nominal sizes because the nominal sizes are multiples of 8; G and Y (each) will less than half the time have an 'extra' octet or very rarely be less than nominal size, and are chosen effectively at random independently so it should take only one or two tries (e.g. openssl commandline dsaparam then gendsa) to get each 'right'.
If you self-sign, which is usually what the easiest to use tools do, both R and S in the signature have the same properties as G and Y in the key, so depending which case you want it will often take 2 or 4 tries, and possibly a few more, to get what you want. You could instead sign with an RSA CA (also fake, of course) in which case the signature is always exactly the size of the modulus and that can be chosen any size up to 16ki bits (2ki octets) although over 4ki bits it will probably get slower.
Since you give no details about what you are actually doing or getting, I can't be more specific.