马上注册,结交更多易友,享用更多功能,让你轻松玩转觅风论坛。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
RSA C#加密源码,不知道写的对不对,请各位指正,只是略微搞懂个原理。还有就是里面肯定有更简洁的方式找公匙私匙,也欢迎大佬补充。
注意:使用RSA加密时密匙必须大于加密内容,否则输出错误信息。
- using System;
- using System.Collections.Generic;
- using System.Numerics;
- using System.Security.Cryptography;
-
- public class HelloWorld
- {
- public static void Main(string[] args)
- {
- Console.WriteLine("STARTED");
- for (int i = 0; i < 1; i++)
- {
- var primes = GenerateLargePrimes(4096);
- CalcKey(primes.Item1, primes.Item2);
- }
- }
-
- private static (BigInteger, BigInteger) GenerateLargePrimes(int bitLength)
- {
- BigInteger firstPrime = _GenerateLargePrime(bitLength);
- BigInteger secondPrime = _GenerateLargePrime(bitLength);
- return (firstPrime, secondPrime);
- }
-
- private static BigInteger _GenerateLargePrime(int bitLength)
- {
- using (var rng = new RNGCryptoServiceProvider())
- {
- BigInteger prime;
- byte[] bytes = new byte[bitLength / 8];
- do
- {
- rng.GetBytes(bytes);
- prime = new BigInteger(bytes);
- prime = BigInteger.Abs(prime);
- prime |= BigInteger.One; // 确保是奇数
- } while (!IsProbablyPrime(prime, 10)); // 使用 Miller-Rabin 测试
-
- return prime;
- }
- }
-
- private static bool IsProbablyPrime(BigInteger source, int certainty)
- {
- if (source == 2 || source == 3)
- return true;
- if (source < 2 || source % 2 == 0)
- return false;
-
- BigInteger d = source - 1;
- int s = 0;
-
- while (d % 2 == 0)
- {
- d /= 2;
- s += 1;
- }
-
- for (int i = 0; i < certainty; i++)
- {
- BigInteger a = RandomIntegerBelow(source - 2) + 1;
- BigInteger temp = d;
- BigInteger mod = BigInteger.ModPow(a, temp, source);
- if (mod == 1 || mod == source - 1)
- continue;
-
- for (int j = 0; j < s - 1; j++)
- {
- mod = BigInteger.ModPow(mod, 2, source);
- if (mod == 1)
- return false;
- if (mod == source - 1)
- break;
- }
-
- if (mod != source - 1)
- return false;
- }
-
- return true;
- }
-
- private static BigInteger RandomIntegerBelow(BigInteger n)
- {
- using (var rng = new RNGCryptoServiceProvider())
- {
- byte[] bytes = n.ToByteArray();
- BigInteger r;
-
- do
- {
- rng.GetBytes(bytes);
- r = new BigInteger(bytes);
- } while (r >= n || r <= 0);
-
- return r;
- }
- }
-
- public static void CalcKey(BigInteger p, BigInteger q)
- {
- BigInteger n = p * q;
- BigInteger phi = (p - 1) * (q - 1);
-
- BigInteger e = FindCoprime(phi);
- BigInteger d = ModInverse(e, phi);
-
- Console.WriteLine("Public key (e, n): (" + e + ", " + n + ")");
- Console.WriteLine("Private key (d, n): (" + d + ", " + n + ")");
-
- BigInteger message = BigInteger.Parse("9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
- BigInteger encrypted = Encrypt(message, e, n);
-
- Console.WriteLine("Encrypted: " + encrypted);
-
- BigInteger decrypted = Decrypt(encrypted, d, n);
- Console.WriteLine("Decrypted: " + decrypted);
- }
-
- public static BigInteger GCD(BigInteger a, BigInteger b)
- {
- if (b == 0)
- return a;
- return GCD(b, a % b);
- }
-
- public static BigInteger FindCoprime(BigInteger r)
- {
- BigInteger e = 2;
- while (e < r)
- {
- if (GCD(e, r) == 1)
- return e;
- e++;
- }
- return 1;
- }
-
- public static BigInteger ModInverse(BigInteger e, BigInteger r)
- {
- BigInteger x, y;
- BigInteger gcd = ExtendedGCD(e, r, out x, out y);
- if (gcd != 1)
- {
- throw new Exception("Inverse doesn't exist.");
- }
- else
- {
- return (x % r + r) % r;
- }
- }
-
- public static BigInteger ExtendedGCD(BigInteger a, BigInteger b, out BigInteger x, out BigInteger y)
- {
- if (a == 0)
- {
- x = 0;
- y = 1;
- return b;
- }
- BigInteger x1, y1;
- BigInteger gcd = ExtendedGCD(b % a, a, out x1, out y1);
- x = y1 - (b / a) * x1;
- y = x1;
- return gcd;
- }
-
- public static BigInteger Encrypt(BigInteger m, BigInteger e, BigInteger N)
- {
- return BigInteger.ModPow(m, e, N);
- }
-
- public static BigInteger Decrypt(BigInteger c, BigInteger d, BigInteger N)
- {
- return BigInteger.ModPow(c, d, N);
- }
- }
复制代码
|
|