1.選擇兩個大素數:p,q;
2.計算所得n:n=p*q;
3.計算中間結果t:t=(p-1)*(q-1);
4.選擇一個e:要求e和t的最大公因數是1(也就是e與t互素);
5.計算所得d:d*e mod t=1,就是說要求d和e的乘積除以t餘1;
(n,e)就是公鑰,(n,d)就是私鑰 dom
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int p = 3; //質數 int q = 17; //質數 if (!IsSuShu(p) || !IsSuShu(q)) { Console.WriteLine("選擇的數字必須是素數"); } int n = p * q; int r = (p - 1) * (q - 1); //歐拉函數 var keyList = GetKeyList(r); var key = keyList.Where(k => k.Item1 != p && k.Item1 != q && k.Item2 != p && k.Item2 != q).LastOrDefault(); int e = key.Item1; //公鑰 int d = key.Item2; //私鑰 long msg = new Random().Next(1, n); //msg必須小於n double encodeMsg = RSA(n, e, msg); double decodeMsg = RSA(n, d, encodeMsg); Console.WriteLine("加密前:" + msg); Console.WriteLine("加密後:" + encodeMsg); Console.WriteLine("解密後:" + decodeMsg); Console.Read(); } private static List<Tuple<int, int>> GetKeyList(int r) { var list = new List<Tuple<int, int>>(); int e = r; int d = 0; while (true) { if (e <= 1) { break; } if (IsSuShu(e)) { if (!IsHaveGongYueShu(r, e)) //r與e互質 { d = GetE2(r, e); if (d > 0) { list.Add(new Tuple<int, int>(e, d)); } } } e--; } if (list.Count == 0) { throw new Exception("找不到合適的數字用來當作公鑰"); } return list; } private static int GetE2(int r, int e) { for (int d = r; d > 0; d--) { if ((d * e) % r == 1 && d != e) //求e關於r的模反元素 { return d; } } return 0; } private static bool IsHaveGongYueShu(int r, int e) { var rList = new List<int>(); var dList = new List<int>(); for (int i = 2; i < r; i++) { if (r % i == 0) { rList.Add(i); } } for (int i = 2; i < e; i++) { if (e % i == 0) { dList.Add(i); } } int result = rList.Where(p => dList.Contains(p)).Count(); if (result > 0) //兩個數字是否有公約數 { return true; } else { return false; } } private static bool IsSuShu(int num) { bool bl = true; for (int i = 2; i <= Math.Sqrt(num) && bl == true; i++) //數字是不是素數 { if (num % i == 0) { bl = false; } } return bl; } public static double RSA(int n, int key, double message) { if (n < 1 || key < 1) { return 0; } double rsaMessage = 0L; rsaMessage = Math.Pow(message, key) % n; return rsaMessage; } } }