The following NodeJS code, when run (v16.8.0), logs 512
to stdout.
const crypto = require("crypto");
const { privateKey } = crypto.generateKeyPairSync("rsa", {
modulusLength: 4096,
});
const sign = crypto.createSign("RSA-SHA256").update("somestringtosign");
const signature = sign.sign(privateKey);
console.log(signature.length); // logs 512
If I change the modulus length to 2048
, then 256
is logged to standard out.
I guess this makes sense, as the RSA spec says: signature, an octet string of length k, where k is the length in octets of the RSA modulus n
. So a 256 bit hash (SHA256), when signed with an RSA key with a 4096 bits modulus, has a 4096 bits (512 bytes) output.
Can the signature length in RS256 indeed be longer than 256, depending on the size of the RSA key used? Is it "weird" to use a modulus that is longer than the hash function used? I see various identity providers that sign JWTs indeed all use 2048 bits modulus, but that might be coincidental.
(I noticed the IETF spec for RS256 says: A key of size 2048 bits or larger MUST be used with these algorithms.
so apparently a modulus of 4096 would be allowed by the spec`)
UPDATE
Thanks to the comments and answers I now understand I asked the "wrong" question. I was (erroneously) expecting the length of the JWT's signature to equal the length of the hash digest produced by the hash algorithm (SHA256). I was therein confusing bits and bytes, because e.g SHA256 produces a digest of 256 bits (not bytes). The signature length I witnessed in my case was 256 bytes (not bits), which I now understand should equal the length of the public key's modulus (which indeed is the case as I was able to verify later).