使用C#实现RSA加密算法(支持中文加密)

您所在的位置:网站首页 rsa解密中文乱码 使用C#实现RSA加密算法(支持中文加密)

使用C#实现RSA加密算法(支持中文加密)

2023-08-15 05:46| 来源: 网络整理| 查看: 265

使用C#实现RSA加密算法(支持中文加密) 1. 简介

信息安全技术选修课上要求自己造轮子实现现代非对称加密算法RSA,自己写了以下试试,感觉还行,分享给有需要的大家。 素数,公钥与私钥都是随机生成的,用base64编码解决了中文加密的问题,没有做签名,但是想加的话也很容易。

2. 需要提前掌握的相关知识 BASE64编码 一文彻底看懂base64编码RSA相关数学知识 3. 原理简述

RSA公开密钥密码体制的原理是: 根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥

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 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) { byte[] b = new byte[8]; b[0] = (byte)(a); b[1] = (byte)(a >> 8 & 0xFF); b[2] = (byte)(a >> 16 & 0xFF); b[3] = (byte)(a >> 24 & 0xFF); b[4] = (byte)(a >> 32 & 0xFF); b[5] = (byte)(a >> 40 & 0xFF); b[6] = (byte)(a >> 48 & 0xFF); b[7] = (byte)(a >> 56 & 0xFF); return b; } public static long BytesToLong(byte[] input) { uint num = (uint)(((input[0] | (input[1] privateKey; set => privateKey = value; } public long N { get => n; set => n = value; } public long Euler_N { get => euler_N; set => euler_N = value; } public void InitPublicKey() //初始化公钥 { RSATools.getP_Q(out p, out q); euler_N = RSATools.getEuler_N(p, q); long e; n = RSATools.getN(p, q); Random radom = new Random(); while (true) { e = radom.Next(655300); if (e > 1 && e < euler_N && RSATools.gcd(e, euler_N) == 1 && RSATools.isPrim(e)) break; } publicKey = new long[2]; publicKey[0] = e; publicKey[1] = n; } public void InitPrivateKey() //初始化私钥 { long d = RSATools.inverse(publicKey[0], euler_N); privateKey = new long[2]; privateKey[0] = d; privateKey[1] = n; } //加密操作 public long encrypt(long plaintext,long[]p_k) => RSATools.getMod(p_k[0], plaintext, p_k[1]); //解密操作 public long decrypt(long ciphertext) => RSATools.getMod(privateKey[0], ciphertext, privateKey[1]); public string getCiphertext(string plaintext, long[] p_k) //加密明文得到密文 { long[] p_long = RSATools.UTF8ToLong(plaintext); long[] c_long = new long[p_long.Length]; for (int i = 0; i < p_long.Length; i++) { c_long[i] = encrypt(p_long[i],p_k); } string c_text = RSATools.longToBase64(c_long); return c_text; } public string getPlaintext(string ciphertext) //解密密文得到明文 { long[] c_long = RSATools.Base64ToLong(ciphertext); long[] p_long = new long[c_long.Length]; for (int i = 0; i < c_long.Length; i++) { p_long[i] = decrypt(c_long[i]); } string p_text = RSATools.longToUTF8(p_long); return p_text; } } } 4.3 可视化界面

前面的RSA类已经完全封装,如果不需要可视化以下代码可省略

4.4 可视化事务处理 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace EXP3_APP { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { RSA a, b; public MainWindow() { InitializeComponent(); a = new RSA(); b = new RSA(); } private void InitPublicKey_A_Click(object sender, RoutedEventArgs e) { a.InitPublicKey(); PublicKey_A.Text = a.PublicKey[0].ToString() + "-" + a.PublicKey[1].ToString(); A_P.Text = a.P.ToString(); A_Q.Text = a.Q.ToString(); A_N.Text = a.Euler_N.ToString(); } private void InitPublicKey_B_Click(object sender, RoutedEventArgs e) { b.InitPublicKey(); PublicKey_B.Text = b.PublicKey[0].ToString() + "-" + b.PublicKey[1].ToString(); B_P.Text = b.P.ToString(); B_Q.Text = b.Q.ToString(); B_N.Text = b.Euler_N.ToString(); } private void InitPrivateKey_A_Click(object sender, RoutedEventArgs e) { a.InitPrivateKey(); PrivateKey_A.Text= a.PrivateKey[0].ToString() + "-" + a.PrivateKey[1].ToString(); } private void InitPrivateKey_B_Click(object sender, RoutedEventArgs e) { b.InitPrivateKey(); PrivateKey_B.Text = b.PrivateKey[0].ToString() + "-" + b.PrivateKey[1].ToString(); } private void Encrypt_Click(object sender, RoutedEventArgs e) { Ciphertext.Text= a.getCiphertext(Plaintext.Text,b.PublicKey); } private void Decrypt_Click(object sender, RoutedEventArgs e) { Plaintext.Text = b.getPlaintext(Ciphertext.Text); } } } 5. 结果展示

结果展示



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3