Are there any difference between RSA encryption/decryption exponent and RSA sign/check exponent?
None. The public key of an RSA public/private pair consists of an exponent and a modulus, whether it's being used to sign or encrypt. The most common exponent is 0x10001.
The Wikipedia article on RSA is pretty good.
There is no structural difference between a RSA key pair used for signing and one used for encryption decryption. In theory, you could use one pair for both, but this opens up ways for new attacks, so it isn't recommended.
On the other hand, there are differences between private and public exponents:
The public exponent can be relatively small, which shortens the key size and speeds up encryption and signature verification.
As Charlie Martin said, 0x10001 = 2^16 + 1 = 65537 is a common choice.
The private exponent, on the other hand, is derived from public key and the modulus' factorization, and usually in the size order of the modulus itself. As it shall stay private, it can't be small (otherwise it is easy to guess), and it also needs to fulfill the arithmetic relation to the public exponent, which makes it automatically large.
This makes naive signing/decryption slower than the corresponding public operations, but on the other hand,
it is possible to speed this up a bit up by using the decomposition of the modulus and the
Chinese Remainder Theorem, i.e. calculating modulo p and q separately instead of modulo m = p·q and
then combining the results.
Note that we distinguish between public (encryption/verification) and private (decryption/signing) exponents,
not between signing/verification and encryption/decryption exponents.
There is no difference between an RSA key intended for signing/verification versus one intended for encryption/decryption in terms of modulus - however the value of the key usage extension in the X509 certificate will differ.
To summarise the detailed answers to Should RSA public exponent be only in {3, 5, 17, 257 or 65537} due to security considerations?) over at security.stackexchange.com:
In theory, all common implementations should allow you to use any prime > 2, but Fermat numbers - numbers of the form 2^n + 1, e.g. 3, 5, 17, 257, 65537 - that are known to be prime are often favoured because they speed up calculations on one side of the operation (encrypt/decrypt, sign/verify) - and 65537 is probably the most common exponent in use at this point in time (2020/11).
However, your specific implementation may restrict the maximum value you can use in practice.
Related
Let's say I have lost a 2048-bit RSA private key but was able to recover a majority of the private exponent d, but still missing a couple of the least significant bytes; for the sake of an example, suppose there are ~2000 bits available.
Having modulus n, public exponent e, and most of the MSBs of d, would it be possible to recover the full private key in a feasible amount of time? I have found some algorithms on GitHub that could achieve a similar task, but with the LSBs of d available, so I am wondering if the same can be done with MSBs available and, if it is possible, whether there are practical implementations of such a method.
I have recently been learning about public/private key encryption in my computer science lessons, and how it works in terms of data encryption/decryption. We also covered how it can be used for digital signatures. However, we didn't go into too much detail on how the actual keys are generated themselves.
I know that it begins with a very large number, which is then passed through some kind of keygen algorithm which returns two distinctive keys, one of which is private and the other is public. Are these algorithms known or are they black box systems? And does one user always have the same pair of keys linked to them or do they ever change at any point?
It just seems like a very mathematical issue, as the keys are linked, yet one is not deducible from the other.
I know that it begins with a very large number, which is then passed through some kind of keygen algorithm which returns two distinctive keys, one of which is private and the other is public.
Well, that's not entirely correct. Most asymmetric algorithms are of course based on large numbers, but this is not a requirement. There are, for instance, algorithms based on hashing, and hashing is based on bits/bytes, not numbers.
But yes, for asymmetric algorithms usually contain a specific algorithm to perform the key pair generation. For instance, asymmetric encryption consists of a triple Gen, Enc and Dec where Gen represents the key pair generation. And the key pair of course consists of a public and a private part.
RSA basically starts off by generating two large random primes, it doesn't start with a single number necessarily.
Are these algorithms known or are they black box systems?
They are known, and they are fundamental to the security of the system. You cannot use just any numbers to perform, e.g., RSA. Note that for RSA there are different algorithms and configurations possible; not every system will use the same Gen.
And does one user always have the same pair of keys linked to them or do they ever change at any point?
That depends on the key management of the system. Usually there is some way of refreshing or regenerating keys. For instance X.509 certificates tend to have a end date (the date of expiry or expiration date), so you cannot even keep using the corresponding private key forever; you have to refresh the certificates and keys now and then.
It just seems like a very mathematical issue, as the keys are linked, yet one is not deducible from the other.
That's generally not correct. The public key is usually easy to derive from the private key. For RSA the public exponent may not be known, but it is usually set to a fixed number (65537). This together with the modulus - also part of the private key - makes the public key. For Elliptic Curve keys a private random value is first produced and the public key is directly derived from it.
You can of course never derive the private key from the public key; that would make no sense - it would not be very private if you could.
In RSA the generated two numbers p and q are very large prime numbers more or less the same size, which are used to calculate N which derives the public/private keys using modulo arithmetic.
The following answer in crypto.stackexchange.com describes in more details how we can start from a random (large) number and use Fermat test and Miller-Rabin tests to reach a number that is very probable to be prime.
From what I can see, Microsoft's RSA CSP always generates identical bitlength pseudo prime numbers. So if the key size is 1024, the P and Q values seem to be (?) guaranteed to be 512 bits each? Does anyone know for sure if this, in fact, is the case?
I'm building an interoperability module between my own RSA implementation and Microsoft's. In my case I have built in a small random variance between P & Q values so for 1024 bit key I could end up with one value being 506 bits and the other 518. On purely experimental basis, if I lock the variance to 0 (i.e. the P & Q values are equal in size) -- Things work the way they should, I soon as I make the size variable Microsoft RSA object responds with "Bad Data" during import process.
I'm looking for a confirmation that Microsoft enforces equal key sizes, so if anyone has any information on it, please post
Before someone has a chance to ask why I had to implement my own RSA provider : CryptoAPI doesn't play nice in a multithreaded environment, it locks the machine keystore on CryptoServiceProvider calls; which means "File not found" (rather cryptic) errors if accessed from multiple threads
For those that care, take a look here: http://blogs.msdn.com/b/alejacma/archive/2007/12/03/rsacryptoserviceprovider-fails-when-used-with-asp-net.aspx
Microsoft's RSA CSP generates and uses private keys which it can export and import in the format described on this page, and looks like this:
BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];
BYTE prime1[rsapubkey.bitlen/16];
BYTE prime2[rsapubkey.bitlen/16];
BYTE exponent1[rsapubkey.bitlen/16];
BYTE exponent2[rsapubkey.bitlen/16];
BYTE coefficient[rsapubkey.bitlen/16];
BYTE privateExponent[rsapubkey.bitlen/8];
So private keys that the CSP can handle (and in particular generate) must have the following properties:
The modulus length, in bits, must be a multiple of 16.
The length of each prime factor must be no more than half the length of the modulus.
The private exponent must not be longer than the modulus.
The private exponent, reduced modulo p-1 (resp. q-1) must be no longer than half the modulus.
Technically, there are infinitely many possible values for the private exponent d, and similarly for exponent1 and exponent2 because all that mathematically matters are the value of d modulo p-1 and q-1; it has been suggested to accept slightly longer private exponent parts if they end up with a lower Hamming weight, because this would lead to some performance benefits. Bottom-line: the format described above will not let you do that.
Other characteristics that the key must have to be acceptable to Microsoft's code (but not directly reported in the description above):
The numerical value of the first prime (p, aka prime1) must be greater than the numerical value of the second prime (q, aka prime2).
The public exponent (here encoded within the rsapubkey field) must fit in a 32-bit integer (unsigned).
Therefore there are many RSA key pairs which are nominally valid as per the RSA standard, but which cannot be handled by Microsoft RSA CSP code. Noteworthy is the last constraint, on the public exponent size: this means that the constraint is more general than just the CSP; if you setup a SSL server where the server's public key (in its certificate) has a public exponent which does not fit in 32 bits, then Internet Explorer will not be able to connect to it.
So, in practice, if you generate RSA key pairs, you will have to make sure that they comply with the rules above. Do not worry: to the best of our knowledge, these rules do not lower security.
My own work/experimentations, doing Mono's (managed) RSA implementation and unit tests, shows that Microsoft implementation requires specific byte[] size when importing RSA parameter values.
It's also a common interoperability issue (there are some SO questions about it) when people using BigInteger to convert their parameters since they often are a bit smaller (e.g. 1 byte less) than what MS expect and needs to be 0-padded.
So I'm pretty sure you can pad your smaller value to make MS accept it, but you'll likely not be able to make it accept a larger value.
How is the encryption algorithm's security dependent on factoring large numbers?
For example, I've read on some math-programming forums that by using the Quadratic Sieve or the General Number Field Sieve, one can factor a 256 bit number with relative ease on commercially available hardware.
How does this translate to being able to break the security of algorithms such as RSA, AES, etc? Is being able to factor numbers the length of the key enough?
Is there anyone knowledgeable in cryptography and encryption algorithms who could shed a little light on it?
RSA, the cryptoalgorithm, relies on number theory, specifically the multiplication of two large primes and the fact this is difficult to factor, to differentiate between public and private keys.
Here's a question on Yahoo answers where someone has given some detail: http://answers.yahoo.com/question/index?qid=20070125183948AALJ40l
It relies on a few facts:
n=p.q is easy to calculate but hard to reverse
Fermat's little theorem: http://en.wikipedia.org/wiki/Fermat%27s_little_theorem
Various results of number theory.
It is not factoring large numbers that is difficult, it is factoring two large numbers whose only factors are themselves large primes, because finding those primes is difficult.
A quick search through my bookmarks gives me this: the mathematical guts of rsa encryption if you're interested in how it works. Also, some explanation here too - just re-read my num-theory notes to be clear.
n = p*q gives you a large number given p,q prime.
phi(n) = (p-1)(q-1). This is an extension of Fermat's little theorem More on why we need this and why it works on my blog here: http://vennard.org.uk/weblog/2010/02/a-full-explanation-of-the-rsa-algorithm/
Which means, if we choose a number E coprime (no common prime factors) to (p-1)(q-1) we can find Es inverse mod phi(n).
Which we do, we find DE = 1(p-1)(q-1) or rather we solve using euclid's greatest common divisor algorithm, extended version.
Now, given all of the above, if we take T^E (pq) we get C. However, if we take (T^E)^D (pq) we get T back again.
AES isn't the same - it isn't public key cryptography. AES takes one key and uses that in both directions, encryption and decryption. The process is basically very difficult to undo, rather like a hash but designed to be reversible. It however, does not rely on factoring large numbers into primes for its security; it relies entirely on the strength of the key and the inability to deduce either the key from the algorithm or the key given known plaintext and the algorithm.
Wikipedia has a good article on AES for high level with a good link that shows you how it works - see here and here. I particularly like the latter link.
How is the an encryption algorithm's security dependent on factoring large numbers?
The missing phrase is "public-key", as in "How is the public key encryption algorithm's security..."
In modern cryptography there two major categories of ciphers, symmetric (secret key) and public-key (which uses a public/private key pair).
Within each category, you will find the key sizes relatively close. For public-key systems like RSA and DH/DSA, both used in OpenPGP e-mail encryption, common key sizes are 1024-bit and larger these days (early 2010). This has to do with the mathematical requirements of suitable keys used to encryption and decrypt messages. For RSA, in short, it is many time easier to generate a factor of two random large prime numbers and do multiplication with them, compared to factoring of very large number that has no small factors. As you've discovered the factoring of very large numbers is the "problem" or approach needed to break RSA via brute force.
Diffie-Hellman / Digital Signature Algorithm (DH/DSA) are based on a different mathematical problem, calculating discrete logarithms.
Due to properties of the public and private key pairs, the search space is limited to factors of large primes numbers, which becomes incredibly sparse, so it makes sense to try to be far more intelligent then simply trying to factor every very large number.
Whereas with symmetric ciphers like AES, RC6, RC4, Twofish, DES and Triple-DES, these algorithms use a random key of a given bit length. Any non-trivial (i.e. 0x000...000 may be a poor key choice) random key is suitable. So these systems, if there is no attack against the algorithm itself, you can simply search brute force through the key space (i.e. try all 2^256 possible keys) to decrypt a message without the secret key. Since any key is suitable, the density of keys is 2^256.
I'm ignoring Quantum Computing (theoretic and practical), mainly because a) I can't give a solid answer, and b) it represents a large paradigm shift that turns much applied mathematics and computer science of computational complexity potentially on its head, that basic understanding is still a moving target. Oh, and most of my enemies don't have a quantum computer yet. :)
I hope that explains the general difference between the two types of crypto systems, such as RSA and AES.
Sidebar: Cryptography is a rich and complex topic, where the basics may be simple enough to understand, and even write a naive ("textbook") implementation, the complex subtleties of a secure implementation makes it best for programmers who are not cryptography experts to use high level crypto-systems including using well-known standard protocols to improve your chances that the cryptography of a system is not the exploitable flaw in a system.
AES is much different, AES creates a SPN, Substitution Permutation Network. It generates s-boxes (substitution boxes) based on polynomial functions generated at encryption time. It runs it through 10-14 rounds of byte-level substitution and bit-level permuting, the bit length of the key determining the number of rounds and the round keys.
RSA is based on factors of large prime numbers which are extremely hard to do computationally, but quite easy to initially encrypt.
RSA is broken by factoring. Actually, RSA is two algorithms, one for (asymmetric) encryption and one for digital signatures; both use the same primitive. In RSA, there is a public value (the modulus, often noted n) which is a product of two (or more) distinct prime factors. Factoring n reveals the private key. Factoring becomes harder when the size of n increases. The current record (published earlier this year) is for a 768-bit integer; it took four years of big computing and hard work by very smart people. The same people openly admit that they have little clue of how they could try the same stunt on a 1024-bit integer (there is a part of the best known factorization algorithm which requires an awful lot of fast RAM, and for a 1024-bit integer that would require a ludicrously huge machine). Current recommendations of key length for RSA are 1024 bits for short term, 2048 bits for long term security. Note that computational cost of RSA increases with key size as well, so we do not want to use really big keys without a good reason. A basic PC will produce about 1000 RSA signatures per second (and per core) with a 1024-bit key, and eight times less with a 2048-bit key. This is still quite good.
There are other asymmetric encryption algorithms, and digital signature algorithms. Somewhat related to RSA is the Rabin-Williams encryption algorithm; factoring also breaks it. Then there are algorithms based on discrete logarithm (in the multiplicative group of numbers modulo a big prime): Diffie-Hellman (key exchange), DSA (signature), El Gamal (encryption)... for these algorithms, factorization is no direct threat; but they rely on the same parts of number theory, and the best known algorithm for discrete logarithm is very similar to the best known algorithm for factorization (and has the same name: GNFS -- as General Number Field Sieve). So it is suspected that an advance in factorization would result from an advance in number theory which would be likely to shed some light on discrete logarithm as well.
The discrete logarithm algorithms can be applied to other groups, the most popular being elliptic curves. Elliptic curves are not impacted by factorization. If factorization became easy, thus scraping RSA and indirectly jeopardizing DSA and Diffie-Hellman, then we would switch to ECDH and ECDSA; standards and implementations exist and are deployed.
"Symmetric cryptography", i.e. hash functions (MD5, SHA-256...), authentication code (HMAC, CBC-MAC...), symmetric encryption (AES, 3DES...), random number generation (RC4...) and related activities, are totally unaffected by factorization. For these algorithms, keys are mere bunches of bits, without any special structure; there is nothing to factor.
Is it possible to encrypt in one order and decrypt in another? For example I've got the following:
plain_text.txt
Public/Private Key pair 1
Public/Private Key pair 2
Example
Encryption:
public1(public2(plain_text.txt))
Decryption:
private1(private2(encrypted))
Is there any encryption algorithm that allows this? Is it even possible?
In most cases you can't change the order of the decryption.
Schemes that allow to reorder decryption are called commutative cryptosystems.
One public key cryptosystem that can be used to build a commutative cryptosystem is
the ElGamal encryption.
Here is just the main idea: Assume g is a generator of
a suitable group G, for which computing discrete logarithms is hard.
Let xA and xB be two private keys,
hA = g xA , and
hB = g xB
be the corresponding public keys. Both keys pairs use the same group
G (i.e. the same modulus p if we use G = Z/(p)). It is one advantage of the
ElGamal scheme that it still is secure if two users share the same group (or modulus).
RSA on the other hand will be insecure.
Encrypting a message m with hA gives the ciphertext
(m hAr, gr).
Note that knowing the secret key xA allows to decrypt because
(gr)xA = hAr
To encrypt the ciphertext a second time one would first re-encrypt the existing
ciphertext with A's public key.
He chooses a random r' and computes
(m hAr hAr', grgr') =
(m hAr+r', gr+r').
The result is just another valid encryption with A's public key.
This re-encryption is necessary to avoid an attack that works for example
against RSA with equal modulus as shown below.
Next, one would encrypt with B's public key giving
(m hAr+r' hBs, gr+r', gs).
Decryption is possible in either order, e.g. knowing xA allows to compute
(gr+r')xA = hAr+r'
and hence one can compute
(m hBs, gs),
which is just what we want: an encryption of m with B's public key.
There are a number of subtleties that need to be observed to get a secure implementation.
And getting this right isn't easy.
For more info see for example the Phd of Stephen Weis, which contains a chapter on commutative encryption.
There are a number of problems if the same idea is tried with "textbook RSA". First to make the encryption commutative it is necessary that both users A and B share the same modulus.
E.g. A uses (n, eA, dA) and B uses (n, eB, dB), where n is the modulus, eA, eB the public keys and dA, dB the secret keys. However, knowing for example (n, eA, dA) allows to factor n, and hence compute B's secret key, which is of course one big flaw.
Now we could encrypt m as
meA mod n,
encrypt again as
meAeB mod n,
decrypt with A's secret key giving
meB mod n,
and decrypt again with B's secret key to get m. That looks fine until one notices that
an attacker who can intercept the two ciphertexts c = meA mod n and c' = meB mod n can use Euclid's algorithm to find r,s such that
r eA + s eB = 1
and then compute
m = cr (c')s mod n.
The idea also works against the solution using RC4 proposed in another answer. Weis's thesis contains a detailed description of the attack.
With most public implementations of RSA it would not be possible. The decryption routine expects the plaintext to be in a specific format (i. e. properly padded) and fails if it's not. Again, on encryption it would apply padding to the plaintext, instead of using the blob as it is.
/*
The math of RSA allows for that, AFAIK, as long as the moduli of the two keys are coprime (which is true almost always). But you'll probably have to roll your own implementation.
*/
Another problem is that the numeric value of the plaintext block should be smaller than the modulus. So the modulus of the first key should be smaller than that of the second key, otherwise no guarantee that the first cyphertext would be a proper plaintext for the second encryption round.
OpenSSL has, I vaguely recall, a no-padding mode. You might have some luck with that.
EDIT: in general, coming up with your own cryptographic primitives is a bad idea in 99.9% cases. If your interest is purely academic, then be my guest; but if you're after a specific piece of applied functionality (i. e. encrypt something so that the consent of two nontrusting parties is needed to decrypt), then you're definitely on the wrong track.
EDIT2: the math of RSA allows for that if the moduli are identical. Scratch paragraph two. But having two keys share the same modulus compromises security very much. If Alice has private key (m, d) and Cindy as private key (m, d') - assuming same m - then Alice can determine d' in O(m) time, given a single plaintext/cyphertext pair from Cindy. Not good.
With public key/private key encryption, the answer is no. PubK1(PubK2(plain.text)) => encrypted.text. You must decrypt with PrivK2(PrivK1(encrypted.text)).
However, if you use a symmetric stream cipher such as RC4, then you could change the order of the decryption (A xor B xor C = C xor B xor A). But that is not a public/private key algorithm obviously.
This would only be true if the encryption algorithm behaved as a specific kind of mathematical group. Most (all?) block encryption algorithms are not such groups.
AFAIK this should be possible with slight modification to RSA. I do not know of any tool which can actually do it though.
No, it does not work. Very simply, you cannot guarantee unique decryption because one modulus is bigger than the other.
EDIT: I'm assuming this is RSA. If not, then I'd have to think about some of the others.
EDIT2: If you are always willing to use the smaller modulus first, then it does work.