This directly shows a major advantage of asymmetric encryption: For symmetrical algorithms the participants have to agree upon a key, for example one picks a key and sends it to the other. But if this is done unencrypted, this can also be intercepted and we have not gained anything. For asymmetric algorithms this step is not needed! We just have to make our public key available (still this has to be done in an authenticated way!). We never have to pass on the private key and can lock it away somewhere safe.

One disadvantage of asymmetric algorithms is their speed, they are mostly significantly slower than symmetric ones.

Asymmetric cryphtography is based on so called one-way functions, for which one direction is easy to calculate, but the other hard.

Here I want to describe the implemention of the RSA cryptosystem in C#. RSA is based on the supposed hardness of prime factorization. For the key creation 2 prime numbers

*p*and

*q*are chosen and their product

*n*is calculated. Calculate

*φ(n) = (p - 1)(q - 1)*and choose

*e*relatively prime to

*φ(n).*Then calculate the multiplicative inverse

*d*of

*e*relative to

*φ(n)*. The public key then is

*(e, n)*and the private one

*(d, n)*. The encrypted message is then calculated as

*c = m^e mod n*, decryption is done by

*m = c^d mod n.*

But enough of the theory, let us come to the code. In C# for this we have the class

*RSACryptoServiceProvider*. The usage of this though is somewhat different than when using code for symmetric encrpytion, due to its different mode of operation: When using RSA, first a public / private key pair has to be created. Then we pass the public key to our communication partner, so he can encrypt for us. Finally we decrypt with our private key.

When creating a new instance of the class

*RSACryptoServiceProvider*automatically a new key pair is created, in the constructor we optionally can set its size etc. With the function

*ExportParameters()*we can export the key (amongst others). This function expects a Boolean parameter, which determines, whether we want to export also the private parameters. We do this when sending them to our decrypting function. We choose the other variant when sending the public key to our communication partner. Via

*ImportParameters()*an

*RSACryptoServiceProvider*instance can import the parameters.

And here the code:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Security.Cryptography;

namespace RSA2

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

byte[] dataToEncrypt = System.Text.Encoding.Unicode.GetBytes("This is a secret.");

byte[] encryptedData;

byte[] decryptedData;

RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

encryptedData = RSAEncrypt(dataToEncrypt, RSA.ExportParameters(false));

MessageBox.Show("Encrypted: " + System.Text.Encoding.Unicode.GetString(encryptedData));

decryptedData = RSADecrypt(encryptedData, RSA.ExportParameters(true));

MessageBox.Show("Decrypted: " + System.Text.Encoding.Unicode.GetString(decryptedData));

}

static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo)

{

byte[] encryptedData;

RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

RSA.ImportParameters(RSAKeyInfo);

encryptedData = RSA.Encrypt(DataToEncrypt, false);

return encryptedData;

}

static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo)

{

byte[] decryptedData;

RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

RSA.ImportParameters(RSAKeyInfo);

decryptedData = RSA.Decrypt(DataToDecrypt, false);

return decryptedData;

}

}

}

## No comments:

## Post a Comment