|

楼主 |
发表于 2022-5-3 22:49:17
|
显示全部楼层
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace RSA
- {
- 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)
- {
- 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] << 8)) | (input[2] << 0x10)) | (input[3] << 0x18));
- uint num2 = (uint)(((input[4] | (input[5] << 8)) | (input[6] << 0x10)) | (input[7] << 0x18));
- return (long)((num2 << 0x20) | num);
- }
- public static long[] UTF8ToLong(string input)
- {
- string input_64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(input));
- byte[] inputByte = Convert.FromBase64String(input_64);
- long[] inputLong = new long[inputByte.Length];
- for (int i = 0; i < inputByte.Length; i++)
- {
- inputLong[i] = (long)inputByte[i];
- }
- return inputLong;
- }
- public static string longToUTF8(long[] input)
- {
- byte[] inputByte = new byte[input.Length];
- for (int i = 0; i < inputByte.Length; i++)
- {
- inputByte[i] = (byte)input[i];
- }
- string inputBase64 = Convert.ToBase64String(inputByte);
- byte[] outputb = Convert.FromBase64String(inputBase64);
- string output = Encoding.UTF8.GetString(outputb);
- return output;
- }
- public static long[] Base64ToLong(string input)
- {
- List<long> output_l = new List<long>();
- string t = "";
- for (int i = 0; i < input.Length; i++)
- {
- t += input[i];
- if (input[i] == '=')
- {
- byte[] tByte = Convert.FromBase64String(t);
- output_l.Add(BytesToLong(tByte));
- t = "";
- }
- }
- return output_l.ToArray(); ;
- }
- public static string longToBase64(long[] input)
- {
- byte[][] inputByte = new byte[input.Length][];
- string output = "";
- for (int i = 0; i < input.Length; i++)
- {
- inputByte[i] = longToBytes(input[i]);
- output += Convert.ToBase64String(inputByte[i]);
- }
- return output;
- }
- }
- }
- 复制代码
- 2.RSA.cs
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace RSA
- {
- class RSA
- {
- private long p, q;
- private long n;
- private long euler_N;
- private long[] publicKey;//0-e 1-n
- private long[] privateKey;//0-d 1-n
- public long P { get => p; set => p = value; }
- public long Q { get => q; set => q = value; }
- public long[] PublicKey { get => publicKey; set => publicKey = value; }
- public long[] PrivateKey { get => 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;
- }
- }
- }
复制代码 |
|