public key for encryption; private key for de-cryption? - encryption

I understand that private and public keys are mathematically related and data encrypted with one key can only be decrpyted with other. My question is that private key is always used to encrypt data whereas public key is always used to de-crypt it? Or can be be vice-vera and if so can you give some example application where its used in other direction (public key to encrypt and private key to decrypt)?

Encryption is about keeping some data confidential; the data is transformed into an opaque blob and the reverse operation requires something that the attacker does not know, i.e. a "secret" or "private" information. The whole point of encryption is that decryption cannot be done with only public information; hence decryption uses the private key. However, there is no problem in letting anybody encrypt data, thus encryption can use the public key.
There are some algorithms (in practice, only one: RSA) which, from a casual glance, appear to be "revertible": you might think about using the private key for encryption, and the public key for decryption. As explained above, there goes confidentiality (if the decryption key is public, then anybody can decrypt, hence the encrypted data cannot be considered as confidential anymore). Such a "reversed encryption" may be used as the basis for a digital signature algorithm, in which there is no notion of confidentiality, but, instead, of verifiable proof of key owner action.
However there is more to RSA than the modular exponentiation. RSA encryption first transforms the input message into a big integer through an operation called "padding". RSA signature generation first transforms the input message into a big integer through another operation which is also called "padding"; but this is not at all the same padding. Padding is essential for security, and the needed characteristics are quite distinct between encryption and signature. For instance, an encryption padding needs a high level of added randomness, whereas a signature padding requires a lot of redundancy (and a hash function, in order to accommodate long input messages).
Talking of signatures as "encryption with the private key" is the way the RSA standard historically put it (hence names such as "md5WithRSAEncryption"), but it is inaccurate (paddings are, and must be, different) and overly specific (it applies only to RSA, not El Gamal, DSA, Diffie-Hellman, NTRU...). This is just a widespread confusion.

If I want to send you a secure message, I would encrypt the message with your public key. That way, only you (knowing the private key) can decrypt it.

Not only can you use a public key for encryption, that is actually the normal mode of operation when you are encrypting for secrecy. This makes sense - anyone can encrypt with the public key, and only the proper recipient can decrypt using their private key.
In many public key systems, signing is mathematically similar to the opposite case - "encrypting with the private key" - but note that the signing operation is fundamentally distinct from the encryption operation. For example, with RSA, signing must use an invariant, verifiable padding method, whereas encryption should use random padding.

It's interchangeable.
Digital Signature -> Private key encrypts, public key decrypts so to verify sender.
Send a message -> Public key encrypts, private decrypts and owner reads the message.
EDIT: People seem to disagree with the "Interchangeable" definition. I need to clarify that I am talking about the mathematical perspective of the operation, not what is best in terms of security. Ofc, you should use keys for their intended operation.
However, Henrick Hellström response in SO thread explains why they are interchangeable mathematically : Are public key and private key interchangeable?

Related

How to encrypt with private key and decrypt with public key in DotNet core RSA

I found several solutions where I can use the RSA Provider to Encrypt a message with the public key and Decrypt it with the private one.
But what I want to have is to Encrypt with the private key and Decrypt with the public key.
I want to store the public key in my app and encrypt a license for example on my dev machine with the private key, send it to the app and let the information decrypt with a public key.
How can I achieve that?
There are two main possibilities here:
1) You actually are referring to signing (a private key operation) and verification (a public key operation).
In RSA signing, the input message is digested, and the digest is combined with a padding scheme, then the private key applied to the padded data.
In RSA verification, the candidate message is digested, the public key is used to undo the private key application, and then the digest is used to validate the padded message. (In PKCS#1 signatures that's "look and see if it's the right answer", for PSS it's more complicated).
If this is what you mean, then you want
Signing
RSA.SignData (hashes the data, then calls SignHash)
RSA.SignHash (completes the operation, is public in case you already hashed the data and want to save on redundancy)
Verification
RSA.VerifyData (hashes the data, then calls VerifyHash)
RSA.VerifyHash (same as above)
2) You want to encapsulate arbitrary data in a transformation using the private key.
The RSA PKCS#1 standards and/or RFCs have no description of what this means. "Encrypt", in RSA, means to apply a chosen padding scheme to the data (PKCS#1 or OAEP) then perform the RSA operation with the public key. "Decrypt" means to perform the RSA operation using the private key, then remove the padding.
The built-in Encrypt and Decrypt methods are performing these operations, including knowing which key to use.
Applying the keys backwards would produce sensible results mathematically, but it doesn't make sense in practice. Assuming we keep "private" meaning "the key that is only known by one party", this means that you have data that is produced by one person that can be read by anyone. If the idea is "I want the readers to know that it was produced by [the private key holder]", then signing is a better operation: It leaves the data in plain form, letting readers do a more optimal read.
RSA encryption is further only defined as a one-shot operation, which means that as a consequence it is limited to a total number of content bytes that is less than the number of bytes in the RSA modulus (11 bytes less for PKCS#1, and bigger reductions in OAEP, depending on the chosen OAEP hash algorithm). Because signing hashes first, the amount of data being processed in RSA is of fixed size. In the normal RSA encryption case the thing being encrypted is a symmetric (AES) key, or some means of building an AES key... and that's much smaller.
In the end, the conclusion of this path is "No, .NET does not allow you to do this".
If you're transporting a license, the industry-standard approach is to sign it. Remember to include a mechanism for replacing the license-issuer key over time, such as writing down the signing certificate. Or use something like PKCS#7/CMS Signed Data, as exposed in .NET by System.Security.Cryptography.Pkcs.SignedCms, since it is a predefined format for transporting the data, signature, and signing certificates -- just check that cms.SignerInfos[0].Certificate is acceptable, and then if CheckSignature(true) doesn't throw, you're good to go.
Encrypting with the private key is signing. Some providers have a verify function that gives the decrypted signature rather than just verifying it.

Crypto++ RSA - Encrypt and sign with the same key pair

I have a program A which needs to send messages to a program B1. The messages must be crypted, and also signed. Which means only B1 can decode, and he must be sure that the message comes from A.
Also, B1 should not be able to encrypt messages and take the role of A towards another instance B2 of the same program.
Theoretically, it should be possible to use a single RSA key pair, with a key for A and a key for B1. Once decoded by B, if the recovered message is validated (such as by a hash function), it must have been sent by A which did not disclose its key to anybody. In that case, both keys are private (which means they have to be exchanged in a secure channel)
1) Is this recommended or is there a strong argument in favor of having separate encryption and signing steps with independent key pairs?
2) Practically, in the Crypto++ library, the PrivateKey class also contains the public key. Is there a way to load a private key only?
Is this recommended or is there a strong argument in favor of having separate encryption and signing steps with independent key pairs?
This is kind of a broad topic. There are a number of things you can do depending on your threat model and risk posture. You should probably start by researching key management and separation.
Since it appears you have selected RSA, then you might want to take a look at Bleichenbacher 1998 “Million message attack” on RSA on Crypto.SE and follow its improvements to 30,000 messages (IIRC). This is where your threat models and risk posture factor into things.
Practically, in the Crypto++ library, the PrivateKey class also contains the public key. Is there a way to load a private key only?
I think you have a misunderstanding of the keys. The public key cannot be disgorged from the private key.
The public key is the {n,e} pair, and the private key is either {n,e,d} or {n,e,d,p,q,dp,dp,u}. If you remove n and e, then the private key won't work. If you remove e alone, then you need to factor n to recover e. Also see RSA function generates public key (e) always to 17 on Stack Overflow.

Are public key and private key interchangeable for RSA?

On the one hand, I hear people saying that the two keys are totally interchangeable, the first one will decrypt what the second one encrypted. This makes me think that the two keys are interchangeable.
But on the other hand, RSA generated keys appear to have different length, and on another topic encrypting with a private key was called “signing” and was deemed less safe than encrypting with a public key. (2)
On top of that comes the idea that the private key should be kept undisclosed when the public key should be openly distributed in the wild. (3)
I planned to receive data from an unique server, so my idea was to keep a public key on that server to encrypt data, and distribute a private key to all the possible customers, but this goes against (3). Conversely, if I distribute public keys and encrypt my data with the private key, the encryption is less safe according to (2).
Should I distribute a public key and encrypt with a private one to satisfy (2) or the other way around?
NB: in my case, performance is not an issue.
The answer depends on whether you are asking your question out of mathematic curiosity, or for purely practical, cryptographic reasons.
If you are implementing a crypto system you should never disclose your private key, so in this sense the keys are absolutely not interchangeable. Furthermore, the usage scenario you describe seems like a good match for authentication rather than confidentiality, so the message that is sent by the server to the clients should indeed be signed and not encrypted. If you need confidentiality as well, you need a few more steps in your protocol.
From a mathematical point of view, the answer is OTOH "yes", presuming you use an internal representation of the private key that only contains the modulus N and the exponent D, and the other exponent E is generated randomly. The formula that describes the relation between the two exponents is 1 = E*D (mod phi(N)), so from a mathematical point of view it doesn't really matter which exponent is which.
But on the other hand, RSA generated keys appear to have different length
If you are using an implementation that produces RSA private keys that are significantly longer than the corresponding public keys, this almost always means the implementation is absolutely not suitable for using public and private keys interchangeably. The difference in length is usually due to a combination of the following:
The public exponent E is not generated randomly, but is a small, fixed constant, such as 3 or 0x10001. The private exponent D will on the other hand be almost as large as the modulus, so the private key data will be almost twice the size of the public key data. If you only got a RSA private key (N,D), your first guess on the public exponent would be either of the values 3 or 0x10001, and it would be easy the check if the guess is correct. Should you want the keys to be interchangeable, the exponent you pick first has to be picked randomly as an odd integer greater than 1 and less than phi(N) and with no prime factors in common with N or phi(N).
The private key data includes the factors P,Q of the public modulus N.
The private key data includes the public exponent E.
Your public key is used to encrypt a message, your private one to decrypt it. Thus with the public key, which you distribute, anyone can encrypt a message safe in the knowledge that only you (or someone with your private key) can decrypt it. To answer your question directly, no they are not interchangeable. You should never distribute your private key.
If you want to share a key with multiple possible customers, then there are really two options. Either you abandon asymmetric cryptography and find a secure way to distribute a symmetric key, for use with something like AES instead of RSA, to each of them, or you ask each of them to generate a key pair and provide you with their public key. Then you can decrypt what comes from the server, and re-encrypt for each customer. The number of customers will help dictate your choice between the two.

Which it better? Pre-generate asymmetric keys or generate them in real-time?

Assuming a keystore is secure and one needs to service around a million keys, is it better to generate asymmetric keys in real-time or is it better to generate a bunch of keys and store them to be used as and when required?
Edit 1: By real time I mean generate a key pair when a user registers for the first time, from then on that key pair is used for all communication with the user.
Asymmetric keys have a public part and a private part; the public part is used to perform the operation which complements that which is done with the private part (e.g. you sign with the private key, and you verify the signature with the public key; or you encrypt data with the public key, and decrypt it with the private key). The point of asymmetric keys is that the private and public parts can be known by distinct entities; namely, that the public part is, well, public (everybody knows it) while the private part remains private.
Consequently, generating an asymmetric key "in real-time" makes little sense in most situations: what gives some value to a private key is that the public key is already known to some other party.
One can still imagine some situations in which "real-time" generation of asymmetric keys can be of use. For instance, SSL connections using one of the "ephemeral Diffie-Hellman" cipher suites: the DH keys, which can be called "asymmetric", are generated for each connection, the public part being then signed by the server (with another asymmetric key, which is not generated on-the-fly: the public key is the one in the server certificate) and then sent to the connecting client. In such a situation, pre-generating DH key pairs and storing them could be viewed as a kind of optimization, but a bad one since DH key pair generation is very fast, and private key storage is a complex and delicate issue.
Edit: if your problem is about key generation upon user registration vs key generation and storage in advance: assuming that server-side key generation is indeed what you want, key generation and storage in advance is worthwhile only as an optimization, if on-the-fly generation proves to be too expensive to handle peaks (occasionally, many users trying to register at the same time). I suggest that you try and bench and make sure that the problem really exists, before implementing a "solution", because private key secure storage is somewhat tricky. RSA key generation is quite fast (on a basic PC, you can easily generate a dozen RSA keys per second), and with discrete-log (DSA, Diffie-Hellman, El-Gamal) or elliptic-curve based cryptosystems, it is even considerably faster (e.g. ten thousands new EC key pairs per second, with a PC).

Is there a way to alter a public key in a way that the decryption can still be done with the private key after some alteration?

In an asymetric encryption scheme, I was wondering if it's possible to achieve the following:
Bob sends to Alice his public key
Alice alters Bob's public key and encrypt some document with it
Alice sends the encrypted document to Bob
Bob retrieve the document but can't decrypt it with his private key
Later, Alice sends some additional information (probably related to the method she used to alter Bob's public key) to Bob
Bob uses this additional information to modify his private key and successfully decrypt the document
Anyone?
I am assuming RSA for the keys generation, encryption and decryption but if it's easier to do with another scheme feel free to comment.
(I assume you talk about RSA.)
Yes it is possible, but not 100%.
The public key is a part of the private key. It contains the modulus and the exponent of the key.
You can completely forget changing the modulus, because you would have to generate a new rsa keypair, which is the same problem as the one we are trying to solve.
But it is possible to change the exponent. You can select any (prime) number between 1 and your exponent as the new exponent and hope that it is coprime with the totient. Without knowing the totient it's impossible to select always a correct exponent. To find out the totient you would have to know the prime factors of the key, which means that you would have to break the key (have fun!).
So, it's actually impossible to have a 100% percent working method to do that, at least not while knowing only the public key.
If you need more information about the theory check here
I hope my idea works.
Let us assume that (e,d,n) is a tuple of the RSA public exponent. The RSA private exponent and the RSA modulus n :
Select a prime number, say p, between 1 and a 256 bit integer.
To encrypt a message m, compute the new public exponent as e*p and the ciphertext as:
c= m^{e*p} mod n.
To decrypt, the receiver should know the prime p, so you send this p later to him, with this he computes
(1) P = p^{-1} mod phi(n)
and
(2) m^e=c^{P} mod n
and
finally m=(m^e)^d mod n. This works as the receiver knows phi(n).
By the way, where can we use this? Is there any application you have in mind for this?
As silky implies in his answer, the way in which RSA is usually used to encrypt a document is in combination with a symmetric algorithm, like AES. A secure random key is generated for the AES algorithm, the documented is encrypted with that AES key, and the AES key is encrypted with the recipient's public key. Both parts are supplied to the recipient.
You can adapt this to your situation simply by sending only the document encrypted with the AES key in the first step, and withholding the AES key encrypted with the recipient's public key until the second step. The first part will be on the order of the original file size, and the second part will be a small, constant size (on the order of the RSA key size).
Hmm, interesting.
You're referring to RSA, I assume?
FYI, RSA isn't actually used to encrypt documents. It's used to exchange keys (keys for a symmetric algorithm, like AES).
So what you're really talking about is an approach that changes the keys.
Technically (mathmatically) if you put a different number in, you'll get a different number out. So that's not an issue; changing the public key in some fashion will (assuming you convince your RSA implementation to use it, or prepare an appropriately different number) result in a different symmetric key, thus an undecryptable document by Bob (because he'll expect a different key).
Really, though, I'm not so sure you care about this. It's a fairly useless thing to do. Perhaps, however, you're actually interested in Key Splitting (or "Secret Sharing" as wikipedia seems to call it).
HTH. I'm by no means an expert.

Resources