[C#] 纯文本查看 复制代码
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);
}
}