1

I want to implement a scenario where two endpoints can securely communicate with each other using public/private key encryption. The scenario is following:

For A to send a message to B:

A encrypts the message using A's private key.

A encrypts the message using B's public key.

A sends the message.

B receives the message.

B decrypts the message using A's public key.

B decrypts the message using B's private key.

B reads the message.

Here is what I have in C# using RSA encryption:

// Alice wants to send a message to Bob:

String plainText = "Hello, World!";
Byte[] plainData = Encoding.Default.GetBytes(plainText);
Byte[] cipherData = null;

RSACryptoServiceProvider alice = new RSACryptoServiceProvider();
RSACryptoServiceProvider bob = new RSACryptoServiceProvider();

var alicePrivateKey = alice.ExportParameters(true);
var alicePublicKey = alice.ExportParameters(false);

var bobPrivateKey = bob.ExportParameters(true);
var bobPublicKey = bob.ExportParameters(false);

RSACryptoServiceProvider messenger = new RSACryptoServiceProvider();
        
messenger.ImportParameters(alicePrivateKey);
cipherData = messenger.Encrypt(plainData, true);

messenger.ImportParameters(bobPublicKey);
cipherData = messenger.Encrypt(cipherData, true);

messenger.ImportParameters(alicePublicKey);
cipherData = messenger.Decrypt(cipherData, true);

messenger.ImportParameters(bobPrivateKey);
cipherData = messenger.Decrypt(cipherData, true);            

String result = Encoding.Default.GetString(alice.Decrypt(cipherData, true));

Clearly, there is something wrong with the following lines:

messenger.ImportParameters(bobPublicKey);
cipherData = messenger.Encrypt(cipherData, true);

Which throws System.Security.Cryptography.CryptographyException with message { "Bad Length" }.

As I can see it is not able to encrypt the data using just the public part of bob's key.

Can someone throw some light on how to properly accomplish what I want to do in C#?

2 Answers 2

4

Two problems here:

A) Your protocol design is wrong. If you want to use RSA to exchange messages, the algorithm is this:

A encrypts message using B's public key

A sends the message

B decrypts the message using B's private key

(B does processing)

B encrypts message using A's public key

B sends the message

A decrypts the message using A's private key

and so on. Notice how A does not know B's private key, and vice versa. The public and private keys are related in such a way that a message encrypted with a public key (known to everyone) can only be decrypted with the corresponding private key (known only to the intendent recipient of the encrypted message). This is the whole point of RSA, actually.

As for implementation in C#, it is quite trivial to do with the Crypto classes once you really understand the underlying concepts. See for example here and here.

B) RSA is good for exchanging small amounts of data. It is meant for key exchange over an insecure channel without the need for a shared secret. For exchanging "normal" data, a symmetric algorithm such as AES is used. So the idea would be generating a random passphrase and IV from A, and sending that to B via RSA as discussed in A; after both parties know the passphrase and IV, they can just encrypt data using AES with the shared key.

This is what SSL does, and you should have a really good reason to roll your own instead of using a standard SSL stream.

Sign up to request clarification or add additional context in comments.

7 Comments

"Notice how A does not know B's private key, and vice versa." - I agree. But, notice how A does not try to access B's private key. A encrypts the message using 1) B's public key so that B can decrypt using its private key and 2) A's private key so that B can decrypt using A's public key and make sure it came from A.
I know SSL and I prefer using it over any custom implementation. But, in my case, I am trying to create a working prototype that works for secure IPC communication. My prototype is targeting a single machine scenario.
But you're saying 'A encrypts X using A's private key' - that's not the way it works. The public key is used for encryption, the private one for decryption.
The double encryption (in the question) means there is an implicit signature (based on encryption with A's private key).
It is perfectly legal for Alice to encrypt the message with Alice's private key and then Bob's public key. When Bob decrypts the message with his private key, he knows that only he could read the message. When he decrypts the resulting message with Alice's public key, he knows it came from Alice. Normally however Alice would instead hash the message, sign the hash with her private key, and then send the signed hash to Bob.
|
1

RSA is used to encrypt data which are smaller than the key. You use symmetric key to encrypt large amount of data and then use the RSA to share the symmetric key.

For further details you might refer to this question : how to use RSA to encrypt files (huge data) in C#

5 Comments

That means, I cannot use RSA to implement the scenario I wish to implement. Can you point to a good example on how to implement the given scenario in C#?
That example is for Symmetric Key Encryption. I want to implement Public/Private key encryption.
I believe the idea was to use Public/Private key encryption to share the symmetric key.
You you mean to say, I should use this algorithm to share a symmetric key and once it is shared, start the communication using Symmetric Key Encryption using that shared key?
Too, bad I can't vote up, need 15 points. :(. But, thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.