Who gives the RSA private key to the opposite party - encryption

I have a very fundamental question on RSA keys. I understood the algorithm at high level. So, when I encrypt using a public key, it can only be (quickly) decrypted using a private key. So if I am communicating with you. How do you get the private key that you will use to decrypt my message? Wasn't this the original issue with DH algorithm as to how to share the keys beforehand.

As you identified, RSA uses a public and a private key. You never give out your private key, but your public key can be sent to others.
Say Alice is communicating with Bob, Alice will give Bob her public key which Bob uses to encrypt a message being sent to Alice. That encrypted message can only be decrypted using Alice's private key, so only Alice can decrypt it with her private key.
The same in the reverse. A message to Bob is encrypted with his public key, which can then only be decrypted using his private key.
The public key can only be used for encryption, and the private key can only be used for decryption.
You can read more about RSA here: https://brilliant.org/wiki/rsa-encryption/

Related

How are public key fingerprints generated?

What information other than the public key itself goes into generating a fingerprint of the public key?
I re-assigned a floating IP address to a different virtual machine in possession of the same public key, and it produces a different public key fingerprint to the previous virtual machine.
So I assume that the public key isn't the sole input in generating a key fingerprint?

Encrypt and decrypt data using public/private key from node

Is it possible to encrypt data using the node public key to store into a state and decrypt it using the node private key? i.e. Is it possible to access the node private key?
The node's public and private keys are an asymmetric key pair, and are meant to be used for signing.
For encryption and decryption, you should use symmetric key cryptography.

Signature with private key

My understanding is
for encryption : I use my recipient's PUBLIC KEY to encrypt my message. He will use his PRIVATE KEY to read my message (only HE can do this) => OK with that
for signing : I use my PRIVATE KEY (since no one has it, it proves my identity). But if my recipient use my PUBLIC KEY, every one could do the same and read my message ! Can anyone explain this ?
Then, I thought that what I should do is
I SIGN my message with my PRIVATE KEY => it proves my identity
I ENCRYPT the result of step 1 using my recipient's PUBLIC KEY => to avoid anyone reading it
HE decrypt with his PRIVATE KEY => only he can do this
HE check my identity with MY PUBLIC KEY
Is that correct ?
Your second guess is not bad.
Usually the way is the following for signing (not encryption):
Calculate a hash (e.g. SHA256) of your message that has to be signed.
Sign this hash (i.e. use your private key for RSA encryption)
That's it. Transfer the plain message and the signed hash to anyone. The message is not encrypted and therefore readable for all recipients. With the help of your public key everyone can decrypt the hash, calculate his or her own hash of your message and as long as both hashes (the self calculated and the signed and decrypted one) are equal, the signature is valid and the message has not beed changed after you have signed it.
In case your message has to be encrypted as well you usually do not use RSA, because it is to slow and to inflexible for larger messages (that means larger than the modulus of the private key, e.g. 2048 bit).
Use a symetric algorithm like AES CBC for the encryption of the message. The coincidentally generated key for encryption can be encrypted with the public key of your recipient and then be transfered.
To sum up signing and encryption using RSA with SHA256 (signature) and AES CBC (encryption):
1. Calculate a SHA256 hash H of your message M.
2. Sign H with your public key, i.e. encrypt H with your RSA private key. That is your signature S.
3. Generate a random key K.
4. Encrypt M with AES CBC to get the encrypted message M'.
5. Encrypt K with the public key of your recipient to get K'.
6. Send K', your signature S and M' to your recipient.
Only the recipient can undo all steps:
Decrypt K' with private key of the recipient to get K (RSA).
Decrypt M' with K (AES CBC) to get the message M.
Decrypt S with your public key (RSA) to get H.
Calculate a SHA256 hash of M.
Compare the calculated hash of step 4 with H (from step 3). If both are equal, the signature is verified successfully.

What is a PGP Secret Key?

I am working on a C# app that encrypts/decrypts messages using PGP implemented by the Bouncy Castle (BC) library. I know PKI but the secret key in PGP throws me off a bit. I looked at the BC examples/source code and the PGP RFC but came away with more questions.
Is Secretkey == Session key?
Is Secretkey == Symmetric key?
Is Secretkey == private key (pub/priv key pairs)? At least the following seems to suggest that the secret key is a private key.
internal static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass)
The RFC says the secretkey contains, among others, information about the publickey or may be the public key itself (at least that's my reading).
Also, somewhere I read the Secretkey is basically a password encrypted privatekey.
When/why would I need a secret key in the PGP protocol? Signing or encrypting?
Thanks
Quoting RFC 4880, OpenPGP, 5.5.1.3. Secret-Key Packet:
A Secret-Key packet contains all the information that is found in a
Public-Key packet, including the public-key material, but also
includes the secret-key material after all the public-key fields.
and 11.2. Transferable Secret Keys:
[...] The format of a transferable
secret key is the same as a transferable public key except that
secret-key and secret-subkey packets are used instead of the public
key and public-subkey packets. Implementations SHOULD include self-
signatures on any user IDs and subkeys, [...]
With other words, the secret key contains the public/private key pair (eg., RSA), but should also contain user IDs and self-signatures. 12.1. Key Structures gives more details on how exported keys are constructed. A helpful tool for understanding the composition of OpenPGP packets are gpg --list-packets [file] or pgpdump [file], which dump the packet structure of their input.
In this case the secret key is a private key. The private key can be used for signing or decryption. Encryption and verification is performed using the public key of the other party. A secret key is nowadays mostly thought of to be a symmetric key, but it can also mean private, especially in older protocols.
There is a lot of this kind of confusion in cryptography, the best thing to do is to look at the context. For instance, if there is a public key, the key cannot be symmetric.

Can I use asymmetric encryption with two private keys?

According to wikipedia (and other sources), asymmetric encryption always works like this:
Party A has a public and private key
Party B encrypts stuff with A's public key
Party A decrypts stuff with their private key
However, I don't want party A to be able to encrypt their own data and only want to them to be able to decrypt it. Using the asymmetric logic this would result in:
Party A has a private key
Party B has a private key (which is party A's public key)
Party B encrypts stuff with their private key
Party A decrypts stuff with their private key
We will be using this for some sort of license generation/checking. Our clients may not generate a license, but the license file must be readable on the client side.
Is this still asymmetric encryption or should I be looking at different methods?
Party A being able to encrypt messages using the public key is absolutely no problem.
Only you could decrypt them (with your private key) and since you have no reason to do so encrypting something with the public key embedded in your application would cause no harm - just a bunch of useless data the user has since he cannot decrypt it.
For the licensing you simply encrypt (or sign - that's enough and then people will be able to read the restrictions etc in the license file but not modidy them) your license file using your private key. The application then decrypts the file using the embedded public key (or validates the signature).
A user extracting the public key and signing a custom license file with it could not use it since it would only work if your private key was embedded in the application (since that's the key necessary to decrypt something encrypted with the public key).
However, he could very well replace your public key with a custom one (where he has the private key, too) and then sign/encrypt his own license file using his private key. That's not a cryptographical issue though - you simply need to add some anti-cracking/modification measures to make it harder to replace the embedded public key. You could do some checksum validations for example.
You have your private key in the safe, and publish your public key. When you create a license you encrypt it with your private key. The client can only decrypt it with your public key.
If you want to restrict your license to a client, ask the client to generate their keypair, and send their public key to you. You then encrypt the license with their public key, then sign it (or encrypt it again) with your private key.
When the client receives the license they will have to
1. verify the signature of (or decrypt) the license you sent them
2. decrypt the verified data using their own private key.
This ensures that 1. only you can send them the license and 2. only they can decrypt it.
What you'd generally do is generate you license on your side, and encrypt it with your private key. Then your client can read it using your public key. This is (very broadly speaking) how certificate schemes (such as used in secure online browsing with HTTPS) work. And yes, that still absolutely counts as asymmetric encryption.
Based on what you're saying, asymmetric encryption is still what you want, it just needs to be done in a different way than you're used to thinking about it.
Let's say you generate a key pair for A. You send A one half of the pair: it doesn't really matter but we'll call it the private half. You encrypt using the public half and send it on to A. Then A can decrypt it. But A won't be able to encrypt a message that appears to come from the A public key since they only have the private half of the key and you can't figure out the other half of the key if you only have half of it, no matter which half you have. So A could only encrypt messages that could be decrypted by the public key that you have kept as a secret.
Of course, as other posters have already said, there are better ways to set up this protocol. Just trying to explain why this is not really an issue once you understand the details of asymmetric encryption and look past what we like to call the key halves and how we usually use them.
You could have a look at Rhino licensing : http://hibernatingrhinos.com/open-source/rhino-licensing/introduction
The other answers already said how to do it ... here just a note that (at least with RSA) the scheme you described in your question is not secure, if it depends on B's key staying secret.
For RSA, the public and private keys are really asymmetric, and you can't simply swap them and expect the same security properties.
If your party B (Bob) encrypts multiple messages with the same public key, an attacker which reads these (ciphertext) messages can with little effort get your public key. The attacker does not get the plaintexts or the private key, but the public key will always become really "public".
For A (Alice), it is even possible to create the public key from the private one, without any message being encrypted with the public one.
I suppose similar caveats are there for other asymmetric cryptosystems - always use them only like they are specified, and proven.
In this case, you would combine two key pairs: B's one to sign/verify the message (to make sure the message was sent by B), and A's one to encrypt/decrypt the message (to make sure only A can read it).
Yes. You can do it with RSA - to do a Diffie-Hellman-like exchange, because not only do the keys from 1 associated pair commute, but keys from different keypairs can commute as well.
alice -> bob: alice.pub
bob -> alice: bob.pub
alice: r = random.secret()
alice -> bob: ( r * (alice.priv * bob.pub) )
bob: r = ( (r * (alice.priv * bob.pub)) * (bob.priv * alice.pub) )
Notice that we did something odd here. We mixed RSA operations from different keypairs in one operation. The objects in parenthesis are effectively a new virtual RSA key, and neither one of these keys is public. Had we tried to create that RSA key directly, either alice or bob would know both keys of the pair. This keypair is effectively a secret key where you write to one end and only the other side can decrypt it, yet you cant decrypt what you wrote yourself, and nobody else can encrypt messages to the other side.
I have never seen anyone mix keypairs like this, but I tested this by writing the code. I had to do something unusual though because normally, applying the private key to the message is for 'signing'. But signing usually hashes the secret and applies the private key to a hash of it; something we do not want. So in my code, once I had the RSA components (D,E,N) extracted into arbitrary precision numbers... ie: decrypt,encrypt,modulus ... I just did:
wormholeSend(me,you,msg) =
(((me ^ {me_D}) \% me_N) ^ {you_E}) \% you_N
The thing that makes it a little tricky is that E (encrypt exponent) is actually a predictable value, but the modulus N is in the public key (E,N). D is private to each party. We need to be careful here, because you and I have a different modulus N.
I did this because I wanted a system where a program is authorized to encrypt keys that can be decrypted by users. Doing this, the user cannot encrypt keys, and the program cannot decrypt them.

Resources