using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System;
using System.IO;
using System.Text;

namespace IRaCIS.Core.Infrastructure.Encryption;

/// <summary>
/// https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html
/// </summary>
public class RSAEncryption
{

    public static AsymmetricCipherKeyPair GenerateRSAKeyPair(int keySize)
    {
        var keyGenerationParameters = new KeyGenerationParameters(new SecureRandom(), keySize);
        var keyPairGenerator = new RsaKeyPairGenerator();
        keyPairGenerator.Init(keyGenerationParameters);
        return keyPairGenerator.GenerateKeyPair();
    }

    public static string ExportPublicKey(AsymmetricKeyParameter publicKey)
    {
        using (StringWriter sw = new StringWriter())
        {
            PemWriter pw = new PemWriter(sw);
            pw.WriteObject(publicKey);
            pw.Writer.Flush();
            return sw.ToString();
        }
    }

    public static string ExportPrivateKey(AsymmetricKeyParameter privateKey)
    {
        using (StringWriter sw = new StringWriter())
        {
            PemWriter pw = new PemWriter(sw);
            pw.WriteObject(privateKey);
            pw.Writer.Flush();
            return sw.ToString();
        }
    }

    /// <summary>
    /// RSA解密
    /// </summary>
    /// <param name="privateKey">私钥</param>
    /// <param name="decryptstring">待解密的字符串(Base64)</param>
    /// <returns>解密后的字符串</returns>
    public static string Decrypt(string privateKey, string decryptstring)
    {
        using (TextReader reader = new StringReader(privateKey))
        {
            dynamic key = new PemReader(reader).ReadObject();
            var rsaDecrypt = new Pkcs1Encoding(new RsaEngine());
            if (key is AsymmetricKeyParameter)
            {
                key = (AsymmetricKeyParameter)key;
            }
            else if (key is AsymmetricCipherKeyPair)
            {
                key = ((AsymmetricCipherKeyPair)key).Private;
            }
            rsaDecrypt.Init(false, key);  //这里加密是true；解密是false  

            byte[] entData = Convert.FromBase64String(decryptstring);
            entData = rsaDecrypt.ProcessBlock(entData, 0, entData.Length);
            return Encoding.UTF8.GetString(entData);
        }
    }/// <summary>

     /// 加密
     /// </summary>
     /// <param name="publicKey">公钥</param>
     /// <param name="encryptstring">待加密的字符串</param>
     /// <returns>加密后的Base64</returns>
    public static string Encrypt(string publicKey, string encryptstring)
    {
        using (TextReader reader = new StringReader(publicKey))
        {
            AsymmetricKeyParameter key = new PemReader(reader).ReadObject() as AsymmetricKeyParameter;
            Pkcs1Encoding pkcs1 = new Pkcs1Encoding(new RsaEngine());
            pkcs1.Init(true, key);//加密是true；解密是false;
            byte[] entData = Encoding.UTF8.GetBytes(encryptstring);
            entData = pkcs1.ProcessBlock(entData, 0, entData.Length);
            return Convert.ToBase64String(entData);
        }
    }
}
