Jump to content

Welcome to Geeks to Go - Register now for FREE

Need help with your computer or device? Want to learn new tech skills? You're in the right place!
Geeks to Go is a friendly community of tech experts who can solve any problem you have. Just create a free account and post your question. Our volunteers will reply quickly and guide you through the steps. Don't let tech troubles stop you. Join Geeks to Go now and get the support you need!

How it Works Create Account
Photo

RSA in C#


  • Please log in to reply

#1
TheQuickBrownFox

TheQuickBrownFox

    Member

  • Member
  • PipPipPip
  • 714 posts
Hi guys! I hope you can help me with this one.

I'm using RSA for my asymmetric encryption in C#. I use RSACryptoServiceProvider.

I want to know how RSACryptoServiceProvider chooses which key (public or private) to use during encrypting. I need to know this because there are times that I would need to encrypt using the public key (exponent, modulus) and there are times when I need to encrypt using the private key (D, modulus).

I've looked into the documentation and other online sources but I can't find answers.

I've tried to experiment by swapping some of the parameters with each other. Didn't work. I've also tried importing incomplete and complete parameters.

Here's some of my code:

public class myRSA
{
private System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
private RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
private static string modPath = "C:\\rsaHamster\\mod.txt";
private static string expoPath = "C:\\rsaHamster\\expo.txt";
private static string dPath = "C:\\rsaHamster\\D.txt";
private static string dpPath = "C:\\rsaHamster\\dp.txt";
private static string dqPath = "C:\\rsaHamster\\dq.txt";
private static string pPath = "C:\\rsaHamster\\p.txt";
private static string qPath = "C:\\rsaHamster\\q.txt";
private static string inverseQPath = "C:\\rsaHamster\\inverseq.txt";

public void export()
{
RSACryptoServiceProvider rsaExport = new RSACryptoServiceProvider();
RSAParameters rsaParam = new RSAParameters();
rsaParam = rsaExport.ExportParameters(true);

fileMgr.write(rsaParam.Modulus,modPath);
fileMgr.write(rsaParam.Exponent,expoPath);
fileMgr.write(rsaParam.D,dPath);
fileMgr.write(rsaParam.DP, dpPath);
fileMgr.write(rsaParam.DQ, dqPath);
fileMgr.write(rsaParam.P, pPath);
fileMgr.write(rsaParam.Q, qPath);
fileMgr.write(rsaParam.InverseQ, inverseQPath);
}

/* TRUE = use private key for encryption, FALSE = use public key for encryption */
public RSAParameters import(bool check)
{
RSAParameters rsaParam = new RSAParameters();

byte[] mod = fileMgr.read(modPath);
byte[] expo = fileMgr.read(expoPath);
byte[] D = fileMgr.read(dPath);
byte[] dp = fileMgr.read(dpPath);
byte[] dq = fileMgr.read(dqPath);
byte[] p = fileMgr.read(pPath);
byte[] q = fileMgr.read(qPath);
byte[] inverseQ = fileMgr.read(inverseQPath);
if (check == true)
{
rsaParam.D = D;
rsaParam.Exponent = expo;
rsaParam.Modulus = mod;

rsaParam.DP = dp;
rsaParam.DQ = dq;
rsaParam.P = p;
rsaParam.Q = q;
rsaParam.InverseQ = inverseQ;

}
else if (check == false)
{
//rsaParam.D = expo;
rsaParam.Exponent = expo;
rsaParam.Modulus = mod;
/*
rsaParam.DP = dp;
rsaParam.DQ = dq;
rsaParam.P = p;
rsaParam.Q = q;
rsaParam.InverseQ = inverseQ;
*/
}
return rsaParam;
}

public byte[] encryptUsingPublic(string msg)
{
RSACryptoServiceProvider pubRsa = new RSACryptoServiceProvider();
RSAParameters rsaParam = new RSAParameters();
rsaParam = this.import(false);
pubRsa.ImportParameters(rsaParam);

Byte[] data = encoding.GetBytes(msg);
Byte[] encrypted = pubRsa.Encrypt(data, false);

return encrypted;
}

/* Message is encrypted using Public Key(Exponent,Modulus) */
public byte[] decryptUsingPrivate(byte[] cipher)
{

RSACryptoServiceProvider decRsa = new RSACryptoServiceProvider();
RSAParameters rsaParam = new RSAParameters();
rsaParam = this.import(true);
decRsa.ImportParameters(rsaParam);
byte[] plain;
plain = decRsa.Decrypt(cipher, false);

return plain;
}

public byte[] encryptUsingPrivate(string msg)
{
RSACryptoServiceProvider privRsa = new RSACryptoServiceProvider();
RSAParameters rsaParam = new RSAParameters();
rsaParam = this.import(true);
privRsa.ImportParameters(rsaParam);

Byte[] data = encoding.GetBytes(msg);
Byte[] encrypted = privRsa.Encrypt(data, false);

return encrypted;
}

/* Message is encrypted using Private Key(D,Modulus) */
public byte[] decryptUsingPublic(byte[] cipher)
{
RSACryptoServiceProvider decRsa = new RSACryptoServiceProvider();
RSAParameters rsaParam = new RSAParameters();
rsaParam = this.import(false);
decRsa.ImportParameters(rsaParam);

byte[] plain;
plain = decRsa.Decrypt(cipher, false);

return plain;
}
}

class MainProg
{
public static void Main(string[] args)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
myRSA myrsa = new myRSA();
myrsa.export();

Console.Write("Enter string to be encrypted: ");
string msg = Console.ReadLine();

string val = null;
Console.WriteLine();
while (val != "c")
{
Console.WriteLine("a. Encrypt using Public then Decrypt using Private (challenge)");
Console.WriteLine("b. Encrypt using Private then Decrypt using Public (key exchange)");
Console.WriteLine("c. Exit");
val = Console.ReadLine();
if (val == "a")
{
byte[] encrypted = myrsa.encryptUsingPublic(msg);
Console.Write("\nEncrypted msg is: ");
Console.WriteLine(encoding.GetString(encrypted));
Console.WriteLine();
byte[] decrypted = myrsa.decryptUsingPrivate(encrypted);
}
else if (val == "b")
{
byte[] encrypted = myrsa.encryptUsingPrivate(msg);
Console.Write("\nEncrypted msg is: ");
Console.WriteLine(encoding.GetString(encrypted));
Console.WriteLine();
byte[] decrypted = myrsa.decryptUsingPublic(encrypted);
}
}
Console.Read();
}
}

I've highlighted the import command in my decryptUsingPublic method. The parameter is set to false since I only need to import the Modulus and Exponent parameters because I'm going to decrypt using the public key only. But if I do this (set parameter to false), I get a bad key error. Now if I set it to true, the error disappears. Now if setting the parameter to true removes the error, I'm no longer sure if the Decrypt function of RSA uses the public key!

I did a simple experiment on RSA. Here's the code:

RSACryptoServiceProvider fRsa = new RSACryptoServiceProvider();
RSACryptoServiceProvider sRsa = new RSACryptoServiceProvider();
RSAParameters param = new RSAParameters();
param = fRsa.ExportParameters(false);
byte[] enc = fRsa.Encrypt(encoding.GetBytes(msg), false);
sRsa.ImportParameters(param);
byte[] dec = sRsa.Decrypt(enc, false);

What this does, basically is initialize two instances of RSA. for the first, I export the public parameters only. I encrypt msg using the first instance of RSA. I use the second RSA and import the parameters of the first to the second. Then I decrypt the cipher of msg using the second. When I do this, the program gives me a Bad Key error. I think it would mean that the first RSA encrypted the msg using the public key since the second RSA, having only the public key imported to it, cannot decrypt the cipher.

So, how do I make RSA encrypt using the private key? I'm sorry if my presentation is fuzzy or incomplete. Please ask any questions if it helps you help me. :)

Hoping for a response from you guys!
  • 0

Advertisements







Similar Topics

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

As Featured On:

Microsoft Yahoo BBC MSN PC Magazine Washington Post HP