使用C#实现RSA加密算法(支持中文加密)
1. 简介
信息安全技术选修课上要求自己造轮子实现现代非对称加密算法RSA,自己写了以下试试,感觉还行,分享给有需要的大家。
素数,公钥与私钥都是随机生成的,用base64编码解决了中文加密的问题,没有做签名,但是想加的话也很容易。
2. 需要提前掌握的相关知识
- BASE64编码 一文彻底看懂base64编码
- RSA相关数学知识
3. 原理简述
RSA公开密钥密码体制的原理是:
根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥
RSA算法的具体描述如下:
公私钥生成流程图:
加密流程图:
解密流程图:
字符流处理流程图:
4.代码实现
4.1 RSA工具类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EXP3_APP
{
class RSATools
{
public static bool isPrim(long num)
//以6为步进单元判断其是否为素数
{
//两个较小数另外处理
if (num == 2 || num == 3)
return true;
//不在6的倍数两侧的一定不是质数
if (num % 6 != 1 && num % 6 != 5)
return false;
long tmp = (long)Math.Sqrt(num);
//在6的倍数两侧的也可能不是质数
for (long i = 5; i <= tmp; i += 6)
if (num % i == 0 || num % (i + 2) == 0)
return false;
//排除所有,剩余的是质数
return true;
}
public static long gcd(long x, long y) => y != 0 ? gcd(y, x % y) : x;
//采用递归的形式,判断两个数是否互质
public static long inverse(long number1, long number3)
//利用欧几里得算法计算m,d的逆元
{
long x1 = 1, x2 = 0, x3 = number3, y1 = 0, y2 = 1, y3 = number1;
long q;
long number4 = 0;
long t1, t2, t3;
while (y3 != 0)
{
if (y3 == 1)
{
number4 = y2;
break;
}
else
{
q = (x3 / y3);
t1 = x1 - q * y1;
t2 = x2 - q * y2;
t3 = x3 - q * y3;
x1 = y1; x2 = y2; x3 = y3;
y1 = t1; y2 = t2; y3 = t3;
}
}
if (number4 < 0)
number4 = number4 + number3;
return number4;
}
public static long getMod(long a, long b, long c)
//利用快速指数模运算,计算m^e mod n
{
//指数 e --> a 底数 m --> b 模数 n --> c
long number3 = 1;
while (a != 0)
{
if (a % 2 == 1)
{
a = a - 1;
number3 = (number3 * b) % c;
}
else
{
a = (a / 2);
b = (b * b) % c;
}
}
return number3;
}
public static long getN(long p, long q) => p * q;
public static long getEuler_N(long p, long q) => (p - 1) * (q - 1);
//求N的欧拉函数
public static void getP_Q(out long p, out long q)
{
Random random = new Random();
while (true)
{
p = random.Next(1000);
q = random.Next(2000);
if (isPrim(p) && isPrim(q)) return;
}
}
public static byte[] longToBytes(long a)
{