1.代码
static void Main(string[] args)
{
a: Console.WriteLine("***********请选择功能**********\n1.RSA加密\n2.RSA解密\n3.退出");
Stream steam = Console.OpenStandardInput();
Console.SetIn(new StreamReader(steam, Encoding.Default, false, 5000));//突破readline输入数据长度的限制
int function = int.Parse(Console.ReadLine());
while (function != 3)
{
if (function == 1)
{
Console.Clear();
Console.WriteLine("*********RSA加密**************");
Console.Write("p为-->");
BigInteger p = BigInteger.Parse(Console.ReadLine());
Console.Write("q为-->");
BigInteger q = BigInteger.Parse(Console.ReadLine());
BigInteger[] key = GenKey(p, q);
Console.Write("待加密的信息为");
BigInteger m = BigInteger.Parse(Console.ReadLine());
DateTime dt1 = System.DateTime.Now;//计时开始
Console.WriteLine("加密后的密文为" + Encrypt(m, key));
DateTime dt2 = System.DateTime.Now;//计时结束
TimeSpan ts = dt2.Subtract(dt1);
Console.WriteLine("加密所用时间为{0}毫秒", ts.TotalMilliseconds);
goto a;
}
else if (function == 2)
{
Console.Clear();
Console.WriteLine("*********DES解密**************");
Console.Write("p为-->");
BigInteger p = BigInteger.Parse(Console.ReadLine());
Console.Write("q为-->");
BigInteger q = BigInteger.Parse(Console.ReadLine());
BigInteger[] key = GenKey(p, q);
Console.Write("待解密的信息为");
BigInteger m = BigInteger.Parse(Console.ReadLine());
DateTime dt1 = System.DateTime.Now;//计时开始
Console.WriteLine("解密后的明文为" + Decrypy(m, key));
DateTime dt2 = System.DateTime.Now;//计时结束
TimeSpan ts = dt2.Subtract(dt1);
Console.WriteLine("解密所用时间为{0}毫秒", ts.TotalMilliseconds);
goto a;
}
}
}
/// <summary>
/// 拓展欧几里得算法
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns>逆元</returns>
public static BigInteger[] ExtendGcd(BigInteger a, BigInteger b)
{
BigInteger x, y;
BigInteger[] arr;
BigInteger[] array1 = new BigInteger[2];
BigInteger[] array2 = new BigInteger[2];
if (b == 0)
{
array1[0] = 1; array1[1] = 0;
return array1;
}
else
{
arr = ExtendGcd(b, a % b);
x = arr[0]; y = arr[1];
array2[0] = y; array2[1] = x - a / b * y;
return array2;
}
}
/// <summary>
/// 生成公钥私钥
/// </summary>
/// <param name="p"></param>
/// <param name="q"></param>
/// <returns>公钥私钥</returns>
public static BigInteger[] GenKey(BigInteger p, BigInteger q)
{
BigInteger fy, a, b,x;
BigInteger[] key = new BigInteger[4];
key[0]= p * q;
key[2] = key[0];
fy =(p-1)*(q-1);
Console.Write("公钥e为");
key[1] = BigInteger.Parse(Console.ReadLine());
a = key[1];
b = fy;
BigInteger[] arr = ExtendGcd(a, b);
x= arr[0];
if (x < 0)
x = x+ fy;
key[3] = x;
Console.WriteLine("公钥为({0},{1})",key[0],key[1]);
Console.WriteLine("私钥为({0},{1})",key[2],key[3]);
return key;
}
/// <summary>
/// 加密
/// </summary>
/// <param name="m">明文</param>
/// <param name="pubkey">钥匙</param>
/// <returns>密文</returns>
public static BigInteger Encrypt(BigInteger m, BigInteger[] pubkey)
{
return BigInteger.ModPow(m,pubkey[1], pubkey[0]);
}
/// <summary>
/// 解密
/// </summary>
/// <param name="c">密文</param>
/// <param name="selfkey">钥匙</param>
/// <returns>明文</returns>
public static BigInteger Decrypy(BigInteger c, BigInteger[]selfkey)
{
return BigInteger.ModPow(c,selfkey[3], selfkey[2]);
}
2.运行结果
3.总结
3.1操作步骤
1.理解RSA算法
2.按照理解写出少位数的密码算法
3.根据要求更改代码,使代码能对大数进行运算
3.2小结
代码用biginteger实现RSA算法以及自带函数,使其能够完成对大输据的处理同时速度也十分乐观。
代码用了一种方法使得控制台读取数据readline可以超过默认长度的限制(详情见代码注释)。