C#.NET CORE .NET6 RSA 私钥签名 公钥验签

发布时间 2023-06-29 16:31:03作者: HackerVirus

C#.NET CORE .NET6 RSA 私钥签名 公钥验签

C#.NET CORE .NET6 RSA 私钥签名 公钥验签(验证签名) ver:20230614

 

环境说明:

.NET CORE 版本:.NET 6 。

 

.NET CORE 对于RSA的支持:

1. .NET 6 中内置了对 PKCS1,PKCS8 2种私钥格式的支持。

2.私钥字符串要去除"-----BEGIN RSA PRIVATE KEY-----"、"-----END RSA PRIVATE KEY-----"、"-----BEGIN PRIVATE KEY-----"、"-----END PRIVATE KEY-----"和换行符。

3.公钥要去除:"-----BEGIN PUBLIC KEY-----"、"-----END PUBLIC KEY-----"和换行符。

 

注意:.NET CORE 加载公钥为 rsaPub.ImportSubjectPublicKeyInfo。

 

核心重点是拿到 .NET CORE 的RSA  对象。

 

签名(双方要协商好编码):

1.将原始报文用UTF8转为byte数组。(参数为byte[] data) 原始报文的编码双方要协商好。

2.调用 SignData(byte[] data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) 方法,其中HashAlgorithmName 是HASH算法,双方要协商好,有:SHA256、SHA1、MD5。SHA256对应JAVA的 SHA256withRSA. (其它还有 SHA1withRSA,MD5withRSA),RSASignaturePadding 一般是Pkcs1.

3.将输出结果转为BASE64字符串。输出结果转字符串的编码,双方要协商好,不一定用BASE64。

 

公钥验签:

1.将原始报文用UTF8转为byte数组。(参数为byte[] data)

2.将签名串(BASE64字符串)用Convert.FromBase64String()转为byte数组。(参数为:byte[] signature)

3.使用  VerifyData(byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) ; 方法验签。其中HashAlgorithmName 是HASH算法,有:SHA256、SHA1、MD5。RSASignaturePadding 一般是Pkcs1.

 

用“支付宝开放平台开发助手”生成一组公私钥:

PKCS8私钥:

MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==

与之匹配的 PKCS1 私钥,用助手转换的:

MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=

与之匹配的公钥:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB

 

 

示例代码:

// See https://aka.ms/new-console-template for more information


using System.Security.Cryptography;
using System.Text;

try
{
    //PKCS8格式私钥
    string strPriPkcs8 = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==";
    //PKCS1格式私钥
    string strPriPkcs1 = "MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=";
    //公钥
    string strPub = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB";

    string strDJM = "泰酷拉!123ABC";//待签名字符串
    strDJM = "泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC";//待加密字符串,超过117字符的测试

    Console.WriteLine("待签名字符串:" + strDJM);

    //一、私钥签名
    //获取私钥对象
    //转为纯字符串,不带格式
    strPriPkcs1 = strPriPkcs1.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
    strPriPkcs1 = strPriPkcs1.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
    RSA rsaPri = RSA.Create();
    rsaPri.ImportRSAPrivateKey(Convert.FromBase64String(strPriPkcs1), out _);
    //如果私钥是PKCS8格式:rsaPri.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKeyPem), out _);

    //待签名字符串 转为byte 数组
    byte[] byToSign = Encoding.UTF8.GetBytes(strDJM); // 编码要和其它语言一致,一般是:UTF8 
    byte[] bySigned = rsaPri.SignData(byToSign, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);//SHA256,对应JAVA,SHA256withRSA,签名结果是 byte 数组
    string strSigned = Convert.ToBase64String(bySigned);//将byte 数组转为字符串,方便传输,一般是base64字符串,其它类型需和对方协商
    Console.WriteLine("签名值:" + strSigned);

    //二、公钥验签(验证签名)
    //获取公钥对象
    strPub = strPub.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
    RSA rsaPub = RSA.Create();
    rsaPub.ImportSubjectPublicKeyInfo(Convert.FromBase64String(strPub), out _);
    //将对方的签名值转为BYTE数组。
    byte[] byToCheckSign = Convert.FromBase64String(strSigned);
    //将原始报文转为byte数组
    byte[] byBody = Encoding.UTF8.GetBytes(strDJM);// 编码要和其它语言一致,一般是:UTF8 
                                                   //验证签名
    bool bCheck = rsaPub.VerifyData(byBody, byToCheckSign, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);//验证签名双方要保持一致
    Console.WriteLine("验证签名:" + bCheck.ToString());

}
catch (Exception ex)
{
    Console.WriteLine("ex:" + ex.Message);
}


Console.WriteLine("Hello, World!");
Console.ReadKey();

 

.NET CORE 与.NET FRAMEWORK的区别。

签名:

.NET CORE:SignData(byte[] data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) ,默认3个参数,后2个得是枚举。

.NET FRAMEWORK:SignData(byte[] buffer, object halg),默认2参数,halg 可以是字符串。

验证签名:

.NET CORE:VerifyData(byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding),默认4个参数,后2个得是枚举。

.NET FRAMEWORK:VerifyData(byte[] buffer, object halg, byte[] signature),默认3参数,halg 可以是字符串。 data(buffer) 和 signature 的顺序有变化。

using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Text;
using RSAExtensions;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.OpenSsl;

namespace ConsoleAppCICC.Net6.RSA
{
    internal class Program
    {
        static void Main(string[] args)
        {
             Console.WriteLine("Hello, World!");
            string message = "这是原始数据";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
            // 可以从文件等读取证书私钥 
            //            string privateKey = @"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXuqAQz+MyeKuC
            //335rPshsHUFxLpZcBj97EiHq9qhvxMhLsMoa3YFvKlwktBoQWzZzgETls1N0H5E/
            //yhV+pljN4TIubfsOQ68TUfJkr9b+S1/25KwOwUmMndqaFb/vcYj1QtWTl65OXOWL
            //l3oKl7j2kwjmwtW8Smm97cEw15ijmRALP3qGvYyzL/YRIOHv+PmDpoMG0dedZRNz
            //u7hdhkU/UrlaRLvDLHyUJPkM+4SJHVUa2epYFMB7OX/b4ZQR0unxIBea2HAo8byG
            //qctOB41cXa6+t8dvRj2DhCXhMHGXKNU8DL9aALLmCbl2UTsJQyvNQ3FaT7TzQYsw
            //gOevjFttAgMBAAECggEBALltxOAukM91QZdAm917HbMwgmvS65M2G6Kht13LnoRT
            //1Qaac14cP4FaG9HArRaaEHe/LXlzZqxN5f+6qDcwrOxqQUP/bOiZ7QbiTUOWkWoL
            //R/VkITCdm6aumJQRVeVu5ZZLWGGA42agGv6duV0ZhPcM833GwwkRvUpv7rsY1i7n
            //ccUObhkv3ql8XjnCcz1rSSkf6W40+dp0pW2mCH6NPeT8kdtBH7mA/ZSK7ZMQbMGg
            //LNdCx069o91POKP/nZ9V9Ex2Bviic2TqpilC6Z/9EryxA0HszknUMX7Lnuhr7Fsb
            //n8wkvYLplebolTOrCy/athEZkGdwCrgdGFk7by/XsdECgYEA9BX0vnhr1d1A9rxz
            //YYt/Xt3DqqtnQ8ETe4CldI3/XIJ3CcMI4f52dAk+Jl9V4vHu4HRKODWjJ67FDExQ
            //Bu+FWUjk01rFSMmbsVJRenRyuGL4X5XTRwMCtcIcxfvYgttLVVpqCsDK2CredAxc
            //u+RZ5eI0/Y4gc+BKzDIbSy1LQ2sCgYEA4kJUQ4BlIQHD2CEj49ORL/WzWk01Wi9A
            //2ilQcVf/xbLeBJd04SemftHLF4ulKM6VZ4KyrTzewwM6rEw31fWo7dgxShwTdnMI
            //Hn3esTdZYK6O6zQ8PuEi/q4hTx4QYXDq63pKoDRTrkQAVZdTe0ujyczPXjdAKwYF
            //obd3sk606ocCgYA7tpdedZVkB7HZ6vaLOZZafgRdX3tu3vBGOY3AuvBrEFvQ3o7w
            //wtD1yEEVICOh1rAq5yg1IiIdFiuMu6qkV7qWwjeA4Wb8TJ4zPkFCpPRf2Y6Ly9qZ
            //N8pU7v0dDmTEdqOyaOEialH1ml87or6ZFN9NVw7BrSCRWKDT3bpBpP4RqwKBgQC/
            //i5u+kaILsWzVOikiJOgTDBTMa/Sw5rQmfTdm3TLhca3XgUknm+OuFXmz8zrdMxb0
            //zIbrdk64FbHET7otXo2m3ZHMxbwMWRIUjkbLDKqT2PORV2VxbjOsHEqCqlb/xxJ6
            //S8uFmQcGzvbhfvzjsoN0wfkEMA4Y3j5CTAn/X/Z1XQKBgGG4qDagG1unSkpNfHfu
            //qwjEjAkSR/pla4vJIaEaA94/gJ21upZfwjUUdRXJbk6W03OfSOlmy2zIeCguV+H/
            //UkMOcmBqVX/tbCQy7weCQwwHU4Dluy7xJIzrgYRXIuV+3zk2D63+LAK84+ksbL61
            //zCnaG86YfYxcClOZ/revxrnd";

            string privateKey = System.IO.File.ReadAllText(@"D:\Code\My\AspectCoreAopDemo\ConsoleAppCICC.Net6.RSA\etc\rsaprivatekey_pass.pem"); 

            //string publicKey = @"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANFVdaJmHSwAj+5ry0MD98sSZ4nH0hgaUWcUwHF7+ptiX8lrnVGeK4yMlHpS5bgaWFwmdwXRaoAzWBWkEg5yV2ECAwEAAQ==";

            //string publicKey = @"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
            //EQEPxnQpyBfDzB4lbEngM+yUxCdj";

            string publicKey = System.IO.File.ReadAllText(@"D:\Code\My\AspectCoreAopDemo\ConsoleAppCICC.Net6.RSA\etc\rsapublic_cert.cert");

            privateKey = privateKey.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
            privateKey = privateKey.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();

            privateKey = privateKey.Replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "").Replace("-----END ENCRYPTED PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();

            publicKey = publicKey.Replace("-----BEGIN CERTIFICATE-----", "").Replace("-----END CERTIFICATE-----", "").Replace("\r", "").Replace("\n", "").Trim();
            publicKey = publicKey.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();

            string sign = string.Empty;
            var r = System.Security.Cryptography.RSA.Create();
            //privateKey = r.ExportPrivateKey(RSAKeyType.Pkcs8);//私钥
            //publicKey = r.ExportPublicKey(RSAKeyType.Pkcs8);//公钥
            //r.ImportPrivateKey(RSAKeyType.Pkcs8, privateKey); //私钥
            //r.ImportPublicKey(RSAKeyType.Pkcs8, publicKey); //公钥

            //r.ImportPkcs8PrivateKey(new ReadOnlySpan<byte>(Convert.FromBase64String(privateKey)), out _); //私钥
            //r.ImportPkcs8PublicKey(Convert.FromBase64String(publicKey)); //公钥

            //r.ImportEncryptedPkcs8PrivateKey(new ReadOnlySpan<byte>(Convert.FromBase64String("123456")), new ReadOnlySpan<byte>(Convert.FromBase64String(privateKey)), out _); //私钥
            //r.ImportPkcs8PublicKey(Convert.FromBase64String(publicKey)); //公钥

            byte[] keyData = Convert.FromBase64String(privateKey);

            // privatekey 私钥字符串,公钥字符串,
            int len = keyData.Length;
            r.ImportEncryptedPkcs8PrivateKey("123456".ToCharArray(), keyData, out len);

            //r.ImportSubjectPublicKeyInfo(Encoding.UTF8.GetBytes(publicKey), out len);
            //r.ImportPublicKey(RSAKeyType.Pkcs8, publicKey);
            //r.ImportPkcs8PublicKey(Convert.FromBase64String(publicKey)); //公钥

            //message 待加密字符串
            var encrypt = Extensions.ToHexString(r.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss));
            Console.WriteLine("System.Security.Cryptography.RSA.Create():" + encrypt);
            var res = r.VerifyData(data, Extensions.FromHexString(encrypt), HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
            Console.WriteLine("System.Security.Cryptography.RSA.Create():" + res);

            sign = Extensions.ToHexString(r.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss));
            Console.WriteLine(sign);
            //string encrypt1 = @"29972173A69BD1018ED99E6B1A0541AE7CEE646D43179AAB18306289F35067234EB9AAC28BF7128B7E7988EFE5378775026795BAE77CD3DA0ECBE3420DBFCB87D595840DF96D7262D5BCFD8BF0A8EF4B6051A4C8C2A970DE086CEA128CF519DD31A31EBF5FC8188A545EAD3D90BE6CE0125A4AE2D863947BF6E69EFDB5DC3BA32BA15D2F7DF2C3192D733B8211194566AAF3D6B95BD16CAC66CD832744004526B62218852B2F923B2CE3C73C92D65311FF80C2E08C79F76F3D949561E40CE776E505F5347B2FEC2C634935C8EF58BCD79B7C6CE27331192944A58353D736B4875C049E26CF111E0F2AEC614B4DF9CFA804DDF9CBED48D33C173D2B396C94B1C72767910BB3A1C3ED757F6410C5B9B72EFFCE63BC37B7AF3643D7721BC89C399A22421C0218E256CD2B5954247C71A2465035677DA3421EA7154964BAC9EE90DDF90921D2A33BAF8BBE2D97BFB36FA8FD35F4411713A1D33F30B26DE4727587F0E15C9F0DB7C7A83FB5058885DADD415F39982EA876D861159CA3ABAD0B7370F910F131AD0EB7644A7A9E8121ACFB714CD5A9CDC55C101B8B0452339BCDC0F04944C46F119396AF2C31EB524BE0C5D3F990D22E2E4CB444AD00B22DE2116BA307ED91AE0F49A2747F4FEC4039F9F57AF14C33FF3CA2962B5085F6F537CCDB98A0A6E4DC5CE20E23D0FD566F25694F7DF074C2031E098A6167CFD37EA0A8AA2BB8";



            // 使用私钥签名
            //using (CngKey cngKey = CngKey.Import(keyData, CngKeyBlobFormat.Pkcs8PrivateBlob))
            //using (RSACng rsa = new RSACng(cngKey))
            //{
            //    sign = Extensions.ToHexString(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss));
            //    Console.WriteLine(sign);
            //}

            // 使用公钥验签
            X509Certificate2 x509 = new X509Certificate2(Convert.FromBase64String(publicKey));
            using (var rsa = x509.GetRSAPublicKey())
            {
                bool result = rsa.VerifyData(data, Extensions.FromHexString(encrypt), HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
                Console.WriteLine("encrypt:" + result);

                result = rsa.VerifyData(data, Extensions.FromHexString(sign), HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
                Console.WriteLine("sign:" + result);
            }

            Console.ReadKey();
        }
    }

    public class Extensions
    {
        public static string ToHexString(byte[] byteArray)
        {
            StringBuilder hexBuilder = new StringBuilder(byteArray.Length * 2);
            foreach (byte b in byteArray)
            {
                hexBuilder.AppendFormat("{0:X2}", b);
            }
            return hexBuilder.ToString();
        }

        public static byte[] FromHexString(string hexString)
        {
            int byteCount = hexString.Length / 2;
            byte[] byteArray = new byte[byteCount];

            for (int i = 0; i < byteCount; i++)
            {
                byteArray[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            }

            return byteArray;
        }


        public static string RSA_Decrypt(byte[] value)
        {
            byte[] deciphered;

            using (var reader = System.IO.File.OpenText(@"D:\Code\My\AspectCoreAopDemo\ConsoleAppCICC.RSA\etc\private.pem"))
            {
                // Extracting the payload
                string privateKeyFile = reader.ReadToEnd();
                var exp = privateKeyFile.Split("\n\n");
                var privateKey = exp[1].Split("\n-----")[0];

                // using the payload to decrypt my data
                using (var rsa = System.Security.Cryptography.RSA.Create())
                {
                    rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out _); //CryptographicException

                    deciphered = rsa.Decrypt(value, RSAEncryptionPadding.Pkcs1);
                }
            }

            return Encoding.Default.GetString(deciphered);
        }

        public static string RSA_Decrypt1(byte[] value)
        {
            string deciphered;

            using (var reader = File.OpenText(@"D:\Code\My\AspectCoreAopDemo\ConsoleAppCICC.RSA\etc\private.pem"))
            {
                string privateKeyFile = reader.ReadToEnd();
                var keyReader = new StringReader(privateKeyFile);

                var decryptEngine = new Pkcs1Encoding(new RsaEngine());

                object pemReader = new PemReader(keyReader).ReadObject();// , new PasswordFinder("azerty")
                var keyPair = (AsymmetricCipherKeyPair)pemReader;
                decryptEngine.Init(false, keyPair.Private);

                deciphered = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(value, 0, value.Length));
            }

            return deciphered;
        }
    }
}