精易论坛

标题: 非对称加密RSA C#加密源码 [打印本页]

作者: 陽陽陽    时间: 2024-6-6 10:09
标题: 非对称加密RSA C#加密源码
RSA C#加密源码,不知道写的对不对,请各位指正,只是略微搞懂个原理。还有就是里面肯定有更简洁的方式找公匙私匙,也欢迎大佬补充。
注意:使用RSA加密时密匙必须大于加密内容,否则输出错误信息。



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




作者: shuya1    时间: 2024-6-6 11:17
支持开源~!感谢分享
作者: 7ian    时间: 2024-6-6 11:57
本帖最后由 7ian 于 2024-6-6 12:00 编辑

我自己用的简单搞个

[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace J7ian.Algorithm
{
    /// <summary>
    /// 创建个RSA类
    /// </summary>

    public class RSA
    {
        //生成RSA对象
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

        /// <summary>
        /// 公钥(用于加密)
        /// </summary>
        public string publicKey = "xxx";

        /// <summary>
        /// 私钥(用于加解密)
        /// </summary>
        public string privateKey = "xxx";

        /// <summary>
        /// 生成新的密钥对:公钥(publicKey)+私钥(privateKey)
        /// </summary>
        public void CreateKey()
        {
            rsa = new RSACryptoServiceProvider();
            //生成1024位公钥私钥
            publicKey = rsa.ToXmlString(false);
            privateKey = rsa.ToXmlString(true);
        }
        /// <summary>
        /// 公钥/私钥 加密:生成base64文本数据;失败返回空文本<br/>
        /// 若key可以是CreateKey是生成的privateKey/publicKey
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key">公钥/私钥</param>
        /// <returns></returns>
        public string Encrypt(byte[] data, string key)
        {
            try
            {
                rsa.FromXmlString(key);
                byte[] re = new byte[0];
                //加密
                for (int i = 0; i < data.Length; i += 117)
                {
                    byte[] cipherbytes = rsa.Encrypt(data.Skip(i).Take(117).ToArray(), false);
                    re = re.Concat(cipherbytes).ToArray();
                }
                return Convert.ToBase64String(re);
            }
            catch (Exception ex)
            {
                Console.WriteLine("RSA-Encrypt:" + ex.Message);
                return "";
            }
        }
        /// <summary>
        /// 私钥解密:根据加密后生成的base64文本数据解密<br/>
        /// 若prikey可以是CreateKey生成的privateKey
        /// </summary>
        /// <param name="base64String"></param>
        /// <param name="prikey">私钥</param>
        /// <returns></returns>
        public byte[] Decrypt(string base64String, string prikey)
        {
            byte[] re = new byte[0];
            try
            {
                rsa.FromXmlString(prikey);
                //解密
                byte[] data = Convert.FromBase64String(base64String);
                for (int i = 0; i < data.Length; i += 128)
                {
                    byte[] cipherbytes = rsa.Decrypt(data.Skip(i).Take(128).ToArray(), false);
                    re = re.Concat(cipherbytes).ToArray();
                }
                return re;
            }
            catch (Exception ex)
            {
                Console.WriteLine("RSA-Decrypt:" + ex.Message);
                return re;
            }
        }

        
    }
}


作者: 艾玛克138    时间: 2024-6-6 16:17
感谢分享,很给力!~
作者: 一指温柔    时间: 2024-6-7 09:43
感谢分享,很给力!~
作者: bianyuan456    时间: 2024-6-7 11:43
已经顶贴,感谢您对论坛的支持!
作者: jtucar    时间: 2024-6-7 12:19
支持开源~!感谢分享
作者: luqing3719    时间: 2024-6-7 15:33

支持开源~!感谢分享
作者: ZHuanR    时间: 2024-6-7 18:02
新技能已get√
作者: 396384183    时间: 2024-6-8 08:49
易语言一键换肤
作者: 光影魔术    时间: 2024-6-9 16:33
感谢分享源码
作者: 情书书书书书    时间: 2024-6-9 21:01
感谢分享
作者: LiuUser    时间: 2024-8-8 12:53
感谢分享
作者: palangg    时间: 2024-9-16 08:03

2024年前来考古,学习一下




欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4