Asymetric encryption algorithm which allows to use public and private key for both encryption and decryption

0

I have the following working asymetric encryption implementation:

private static RSAParameters privateKey;
private static RSAParameters publicKey;

private static void RSA()
{
  var rsa = new RSACryptoServiceProvider();
  privateKey = rsa.ExportParameters(true);
  publicKey = rsa.ExportParameters(false);

  byte[] originalMessage = GenerateRandomData();
  byte[] encryptedMessage = Using(publicKey).Encrypt(originalMessage, false);
  byte[] decryptedMessage = Using(privateKey).Decrypt(encryptedMessage, false);
  Debug.Assert(originalMessage.SequenceEqual(decryptedMessage));
}

private static RSACryptoServiceProvider Using(RSAParameters parameters)
{
  RSACryptoServiceProvider encryptor = new RSACryptoServiceProvider();
  encryptor.ImportParameters(parameters);
  return encryptor;
}

private static byte[] GenerateRandomData()
{
  Random rnd = new Random();
  byte[] originalData = new byte[10];
  rnd.NextBytes(originalData);
  return originalData;
}

I use this to encrypt data with the recipient's public key [Using(publicKey).Encrypt(originalData)] so that the receiver only can decrypt the data [Using(privateKey).Decrypt(encryptedData)].

Now I want to reuse asymetric encryption for the following use case: The recipient publishes data and everyone who knows the recipient's public key (which is basically everyone in the system, but nobody outside the system e.g. a protection against leaking readable data to the public) can read it. The publisher uses his private key to encrypt and his public key would be used to decrypt:

byte[] originalData = GenerateRandomData();
byte[] publishedData = Using(privateKey).Encrypt(originalData, false);
byte[] retrievedData = Using(publicKey).Decrypt(publishedData, false);
Debug.Assert(originalData.SequenceEqual(retrievedData));

However this yields a

System.Security.Cryptography.CryptographicException
  HResult=0x8009000D
  Message=Keyset does not exist.

I do not want to use a different public-private-key-pair for data publishing part, especially in this scenario it means making public a private key. It already sound awkward when typing...

EDIT: Is there an asymetric encryption contained in .NET framework which allows me to use both keys (public and private) in both directions where if one key is used for encryption only the other one can be used to decrypt?

c#
encryption
public-key-encryption
public-key
asked on Stack Overflow Aug 24, 2019 by David • edited Aug 24, 2019 by David

1 Answer

1

RSA signing is not the same as encrypting with the private key.

PKCS#1 v1.5 signature:

  • Hash the content with a chosen algorithm.
  • Create a DigestInfo value to represent the hash.
  • Apply padding to make a message almost, but not quite, the size of the modulus (details omitted here).
  • Apply the RSA primitive with the private key

Note that last step doesn’t say “encrypt”.

The RSA classes in .NET do the padding and such for you, so they expose Sign/Verify and Encrypt/Decrypt. You can’t use them for cross purposes, and you can’t use these classes for the RSA primitive (aka “raw RSA”).

answered on Stack Overflow Aug 24, 2019 by bartonjs

User contributions licensed under CC BY-SA 3.0