Does RSA2048 key modulus have to be exactly 2048 bits long? - cryptography

Does RSA2048 key modulus have to be exactly 2048 bits long, or does it mean at least 2048 bits and it can be for example 2080 bits long?

The key size of RSA is defined to be the size in bits of the modulus. The RSA private exponent may actually be shorter than the modulus. So yes, the modulus has to be 2048 bits long, otherwise you'd have a different key size.
One implication is that the highest order bit is always set to one. With RSA it is very important to keep in mind that all values are stored as unsigned integers.

Related

What is the entropy of XORed CSPRNG bytes with low entropy hash?

Let’s say I take 256 bits from a CSPRNG and assume it is perfectly 256 bits of entropy. Call this rand.
Then let’s say I take the sha256 of the ASCII text “password”. Call this hash.
Now we XOR rand and hash. Call this mixed.
Is the entropy of mixed less than that of rand?
If so, is there a formula for calculating its entropy?
Example below: What is the entropy of mixed as a function of rand and weak_hash
#!/usr/bin/python3
import hashlib, os
def main():
rand = int(os.urandom(32).hex(),16)
weak_hash = int(hashlib.sha256(b'password').digest().hex(),16)
mixed = ("%064x" % (rand ^ weak_hash))
print(mixed)
main()
You are describing a one-time-pad. If the key stream: the output of the CSPRNG is fully random then the ciphertext will be indistinguishable from random as well.
Of course the output of CSPRNG is not fully random. However, if the CSPRNG is well seeded with enough entropy then you'd have the same security as a stream cipher, which mimics a one time pad.
So the output (mixed) will be as random as the CSPRNG, as long as the CSPRNG doesn't get into a previously encountered state. That should basically only happen if the entropy source fails.

What's the proper way to get a fixed-length bytes representation of an ECDSA Signature?

I'm using python and cryptography.io to sign and verify messages. I can get a DER-encoded bytes representation of a signature with:
cryptography_priv_key.sign(message, hash_function)
...per this document: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
A DER-encoded ECDSA Signature from a 256-bit curve is, at most, 72 bytes; see: ECDSA signature length
However, depending on the values of r and s, it can also be 70 or 71 bytes. Indeed, if I examine length of the output of this function, it varies from 70-72. Do I have that right so far?
I can decode the signature to ints r and s. These are both apparently 32 bytes, but it's not clear to me whether that will always be so.
Is it safe to cast these two ints to bytes and send them over the wire, with the intention of encoding them again on the other side?
The simple answer is, yes, they will always be 32 bytes.
The more complete answer is that it depends on the curve. For example, a 256-bit curve has an order of 256-bits. Similarly, a 128-bit curve only has an order of 128-bits.
You can divide this number by eight to find the size of r and s.
It gets more complicated when curves aren't divisible by eight, like secp521r1 where the order is a 521-bit number.
In this case, we round up. 521 / 8 is 65.125, thus it requires that we free 66 bytes of memory to fit this number.
It is safe to send them over the wire and encode them again as long as you keep track of which is r and s.

What is the difference between “SHA-2” and “SHA-256”

I'm a bit confused on the difference between SHA-2 and SHA-256 and often hear them used interchangeably. I think SHA-2 a "family" of hash algorithms and SHA-256 a specific algorithm in that family. Can anyone clear up the confusion.
The SHA-2 family consists of multiple closely related hash functions. It is essentially a single algorithm in which a few minor parameters are different among the variants.
The initial spec only covered 224, 256, 384 and 512 bit variants.
The most significant difference between the variants is that some are 32 bit variants and some are 64 bit variants. In terms of performance this is the only difference that matters.
On a 32 bit CPU SHA-224 and SHA-256 will be a lot faster than the other variants because they are the only 32 bit variants in the SHA-2 family. Executing the 64 bit variants on a 32 bit CPU will be slow due to the added complexity of performing 64 bit operations on a 32 bit CPU.
On a 64 bit CPU SHA-224 and SHA-256 will be a little slower than the other variants. This is because due to only processing 32 bits at a time, they will have to perform more operations in order to make it through the same number of bytes. You do not get quite a doubling in speed from switching to a 64 bit variant because the 64 bit variants do have a larger number of rounds than the 32 bit variants.
The internal state is 256 bits in size for the two 32 bit variants and 512 bits in size for all four 64 bit variants. So the number of possible sizes for the internal state is less than the number of possible sizes for the final output. Going from a large internal state to a smaller output can be good or bad depending on your point of view.
If you keep the output size fixed it can in general be expected that increasing the size of the internal state will improve security. If you keep the size of the internal state fixed and decrease the size of the output, collisions become more likely, but length extension attacks may become easier. Making the output size larger than the internal state would be pointless.
Due to the 64 bit variants being both faster (on 64 bit CPUs) and likely to be more secure (due to larger internal state), two new variants were introduced using 64 bit words but shorter outputs. Those are the ones known as 512/224 and 512/256.
The reasons for wanting variants with output that much shorter than the internal state is usually either that for some usages it is impractical to use such a long output or that the output need to be used as key for some algorithm that takes an input of a certain size.
Simply truncating the final output to your desired length is also possible. For example a HMAC construction specify truncating the final hash output to the desired MAC length. Due to HMAC feeding the output of one invocation of the hash as input to another invocation it means that using a hash with shorter output results in a HMAC with less internal state. For this reason it is likely to be slightly more secure to use HMAC-SHA-512 and truncate the output to 384 bits than to use HMAC-SHA-384.
The final output of SHA-2 is simply the internal state (after processing length extended input) truncated to the desired number of output bits. The reason SHA-384 and SHA-512 on the same input look so different is that a different IV is specified for each of the variants.
Wikipedia:
The SHA-2 family consists of six hash functions with digests (hash
values) that are 224, 256, 384 or 512 bits: SHA-224, SHA-256, SHA-384,
SHA-512, SHA-512/224, SHA-512/256.

RSA and exponent not relatively prime with Euler Phi

I would like to know which drawbacks are there if the public exponent (e) is not coprime with the Euler phi (phi(N)) in RSA. That is to say GCD(e, phi(n)) != 1.
As far as I know the drawback is that in this way we are not sure that there exists a d such that e*d = 1 mod phi. Are there any other drawbacks?
A modular multiplicative inverse of a mod n exists if and only if gcd(a, n)= 1. So, yes, they must be coprime.
Generally, just use 65537 as your public key exponent. There are no advantages for choosing a random e, and 65537 is sufficient large to protect against Coppersmith's Attack and has some qualities that make it particularly efficient for square and multiply algorithms to work with.
Let us take a example: N=65 and e=3.
Then, if we encrypt the plaintext 2, we get 2^3 mod 65 = 8
However, if we encrypt the plaintext 57, we get 57^3 mod 65 = 8
Hence, if we get the ciphertext 8, we have no way of determining whether that corresponds to the plaintext 2 or 57 (or 32, for that matter); all three plaintexts would convert into that one ciphertext value.
Making sure e and ϕ(N) are relatively prime ensures this doesn't happen.

Private key length bytes

So im generating 2048 RSA keypair. But when i look at the private key the lenght is only 1232 bytes. Does this have anything to do with the 2048 or is the 2048 just the modulus size?
The size of a RSA key is expressed in bits, not bytes. 2048 bits are 256 bytes.
A bare-bone RSA private key consists in two integers, the modulus (a big composite integer, its length in bits is the "RSA key length") and the private exponent (another big integer, which normally has the same size than the modulus). However, the modulus and the private exponent have a bit of internal structure, and knowing details about that structure allows for faster implementations (by a factor of about 4). Hence, RSA private keys usually include some more data.
Namely, if the modulus is n and is the product of two prime numbers p and q, then the private key includes:
the modulus n (256 bytes for a 2048-bit key)
the public exponent e (small, often 65537, i.e. can be encoded over 3 or 4 bytes)
the private exponent d (about 256 bytes)
the factors p and q (128 bytes each)
d reduced modulo p-1 (128 bytes)
d reduced modulo q-1 (128 bytes)
1/q mod p (the inverse of q modulo p; 128 bytes)
for a grand total of about 1160 bytes. Then there is a bit of overhead for the encoding, because all those integers could have lengths slightly different (for instance, nothing really requires that p and q have the exact same size; also, e could be greater than that). The standard structure uses ASN.1, which implies a few extra bytes here and there. It is also common to wrap the structure into a bigger structure which also identifies the key as being a key for RSA. 1232 bytes is compatible with a 2048-bit RSA key encoded in PKCS#8 format.
For details on RSA, have a look at PKCS#1.
Don't forget that 2048 is the length of the modulus in bits, but your measurement of the private key is in bytes. The private key is the modulus and the multiplicative inverse of the public exponent, and depending upon the toolkit you're using, it might also store your CN, DN, (for x509 keys) or subkeys (for GPG keys), so just comparing sizes may not be useful.
Other than the required values (of which the modulus is one, as #sarnold points out) and the fact that you are quite literally comparing bits and bytes, some implementations also compute a few other values up front and store them along with the key, as an optimization. For example, I am not certain but I believe I read that some implementations store the product (p-1)(q-1) (recall that the modulus n is actually the product pq, where p and q are prime).
#Thomas Pornin,
I use both ssh-keygen and openssl genpkey to generate a keypair, each with 2048 keysize, and then print the content, it is like this:
Private-Key: (2048 bit)
modulus:
00:bd:92:7f:da:4f:8f:b0:33:23:0f:d7:f4:12:39:
5d:4d:32:48:1b:6e:de:2d:a5:b9:83:7f:d2:f2:dc:
39:c5:f3:6f:6a:5f:8a:9d:21:9c:01:51:a7:22:99:
70:0d:03:2e:12:63:f2:44:5f:a7:6e:cc:df:44:d9:
8b:b2:7e:fd:8c:c3:ae:62:3e:1e:7e:7a:89:1d:94:
de:86:24:36:d6:f8:23:32:aa:4d:dc:c7:44:87:9d:
68:a5:31:f4:ff:a3:ff:9d:01:57:c9:82:9b:9b:e1:
1c:0f:45:2b:0f:f2:ce:95:4c:13:fb:e9:99:19:82:
64:97:18:77:13:bb:a9:8c:1f:a1:02:cf:92:1a:4d:
13:16:55:8d:06:a8:32:8b:43:80:12:a4:98:77:a7:
cb:7b:4f:e7:be:4e:eb:7b:52:1f:04:49:c9:03:5a:
5b:70:f8:db:c7:8c:99:62:32:cd:3f:fc:70:7f:5e:
de:e9:52:04:f6:19:df:c7:21:bd:28:d8:31:e1:43:
27:ff:ce:43:3a:83:9e:97:69:93:35:46:1f:7f:1d:
4a:43:7f:7f:be:fd:62:c6:f8:a3:9e:07:df:75:4b:
08:4a:47:59:e6:b3:e2:d8:40:29:d4:de:88:54:f5:
6b:e6:e8:77:d5:71:73:c0:1c:0e:8a:b1:ad:25:82:
79:05
publicExponent: 65537 (0x10001)
privateExponent:
42:98:a7:9f:9a:d9:a0:8d:a6:60:97:7d:df:b5:15:
48:dc:44:26:97:01:28:4a:12:ec:d6:47:d6:17:75:
98:4b:d7:b5:27:d1:3b:38:26:64:f4:39:61:d7:43:
5c:de:e4:1d:83:cd:05:26:11:5c:c4:4e:1f:12:c9:
97:b0:33:04:73:6d:dc:87:74:10:fc:9d:14:ae:4a:
aa:17:28:c8:c6:2d:1f:4c:62:c4:0f:a0:cc:7f:88:
d6:97:c1:38:d9:75:1f:c3:ec:02:17:86:f0:f0:d8:
f9:a8:53:e3:6b:6a:15:5a:bf:9e:7c:c6:d3:06:52:
ae:1d:e3:1f:24:8b:00:75:33:ee:aa:b0:69:52:a4:
07:41:60:35:34:67:10:ac:40:b3:5b:70:d7:a7:9c:
c5:aa:08:2e:f5:7b:64:4f:8d:ff:ca:f9:2e:5e:4c:
a9:ef:74:74:18:9b:14:c5:96:ce:70:43:18:ff:2d:
25:d6:5a:15:15:11:dc:e9:6e:98:ea:b0:1d:73:d0:
73:e2:5c:e7:f9:b8:03:a8:8d:1f:81:ca:87:97:b5:
82:3a:f2:71:15:0c:34:1f:63:8d:b8:03:99:6f:e7:
4d:c0:b7:c9:9a:63:60:10:af:7a:5b:db:df:aa:a3:
81:8e:6c:44:b0:77:ee:33:0c:00:e1:67:a8:e1:8d:
61
...
...
So, the private exponent is the 256bytes(2048bits), not the modulus, isn't it?