小枫嘎嘎 发表于 2024-6-7 16:20:33

非对称加密RSA C#加密源码

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;
            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);
    }
}


老子 发表于 2024-6-8 08:22:46

我知道错了,感谢大神分享

咬牙坚持 发表于 2024-6-9 00:24:59

66666666666666666666

2549051527 发表于 2024-6-9 16:27:12

想学唉,可惜现在的我啥都不会

gwm231 发表于 2024-6-10 08:29:25

不错不错 支持下

孤独 发表于 2024-6-11 00:31:37

非常不错,感谢分享!

2098817979 发表于 2024-6-11 14:57:40

9999999999999999

好吧你又赢了 发表于 2024-6-12 05:23:43

人设人阿松大

汨黎 发表于 2024-6-12 19:49:45

谢谢分享,下载测试

舞步 发表于 2024-6-13 10:15:48

支持,赞
页: [1] 2 3 4 5 6
查看完整版本: 非对称加密RSA C#加密源码