163 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						||
using System.IO;
 | 
						||
using System.Security.Cryptography;
 | 
						||
using System.Text;
 | 
						||
 | 
						||
namespace APT.Utility
 | 
						||
{
 | 
						||
 | 
						||
    public static class RSAHelper
 | 
						||
    {
 | 
						||
        public static (byte[] PublicKey, byte[] PrivateKey) GenerateRsaKeysByte()
 | 
						||
        {
 | 
						||
            using var rsa = RSA.Create(2048); // 推荐2048位密钥
 | 
						||
            var privateKey = rsa.ExportRSAPrivateKey();// rsa.ExportRSAPrivateKeyPem(); // 私钥(PEM格式)
 | 
						||
            var publicKey = rsa.ExportRSAPublicKey();//.ExportRSAPublicKeyPem();   // 公钥(PEM格式)
 | 
						||
 | 
						||
            return (publicKey, privateKey);
 | 
						||
        }
 | 
						||
 | 
						||
        public static (string PublicKey, string PrivateKey) GenerateRsaKeys()
 | 
						||
        {
 | 
						||
            // 推荐2048位密钥
 | 
						||
            using var rsa = RSA.Create(2048);
 | 
						||
            //var privateKey = Encoding.UTF8.GetString(rsa.ExportRSAPrivateKey());// 私钥(PEM格式)
 | 
						||
            //var publicKey = Encoding.UTF8.GetString(rsa.ExportRSAPublicKey());  // 公钥(PEM格式)
 | 
						||
            var privateKey = rsa.ExportRSAPrivateKeyPem();
 | 
						||
            var publicKey = rsa.ExportRSAPublicKeyPem();
 | 
						||
 | 
						||
            //签名
 | 
						||
            byte[] dataBytes = Encoding.UTF8.GetBytes("13245");
 | 
						||
            byte[] signatureBytes = rsa.SignData(
 | 
						||
                dataBytes,
 | 
						||
                HashAlgorithmName.SHA256, // 推荐SHA256
 | 
						||
                RSASignaturePadding.Pkcs1  //.Pkcs1 // 或RSASignaturePadding.Pss
 | 
						||
            );
 | 
						||
            string strSignData = Convert.ToBase64String(signatureBytes);
 | 
						||
 | 
						||
 | 
						||
            // //验证 true
 | 
						||
            // byte[] dataBytes2 = Encoding.UTF8.GetBytes(strSignData);
 | 
						||
            // byte[] signatureBytes2 = Encoding.UTF8.GetBytes("13245");
 | 
						||
 | 
						||
            // var rrr = rsa.VerifyData(
 | 
						||
            //    dataBytes2,
 | 
						||
            //    signatureBytes2,
 | 
						||
            //    HashAlgorithmName.SHA256,
 | 
						||
            //    RSASignaturePadding.Pkcs1  //.Pkcs1 // 必须与签名时一致
 | 
						||
            //);
 | 
						||
 | 
						||
            // //验证 false
 | 
						||
            // byte[] signatureBytes3 = Encoding.UTF8.GetBytes("1324235");
 | 
						||
            // var rrr3 = rsa.VerifyData(
 | 
						||
            //    dataBytes2,
 | 
						||
            //    signatureBytes3,
 | 
						||
            //    HashAlgorithmName.SHA256,
 | 
						||
            //    RSASignaturePadding.Pkcs1  // 必须与签名时一致
 | 
						||
            //);
 | 
						||
 | 
						||
 | 
						||
            return (publicKey, privateKey);
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 使用RSA私钥对数据进行签名
 | 
						||
        /// </summary>
 | 
						||
        public static byte[] SignData(byte[] data, string privateKey)
 | 
						||
        {
 | 
						||
            using (var rsa = RSA.Create())
 | 
						||
            {
 | 
						||
                rsa.FromXmlString(privateKey);
 | 
						||
                // 使用SHA256作为哈希算法,PKCS#1 v1.5填充模式
 | 
						||
                return rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 使用RSA公钥验证签名
 | 
						||
        /// </summary>
 | 
						||
        public static bool VerifyData(byte[] data, byte[] signature, string publicKey)
 | 
						||
        {
 | 
						||
            using (var rsa = RSA.Create())
 | 
						||
            {
 | 
						||
                rsa.FromXmlString(publicKey);
 | 
						||
 | 
						||
                return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        public static string ExportPublicKeyPem(this RSA rsa)
 | 
						||
        {
 | 
						||
            var exported = rsa.ExportSubjectPublicKeyInfo();
 | 
						||
            return $"-----BEGIN PUBLIC KEY-----\n{Convert.ToBase64String(exported, Base64FormattingOptions.InsertLineBreaks)}\n-----END PUBLIC KEY-----";
 | 
						||
        }
 | 
						||
 | 
						||
        public static string ExportPrivateKeyPem(this RSA rsa)
 | 
						||
        {
 | 
						||
            var exported = rsa.ExportPkcs8PrivateKey();
 | 
						||
            return $"-----BEGIN PRIVATE KEY-----\n{Convert.ToBase64String(exported, Base64FormattingOptions.InsertLineBreaks)}\n-----END PRIVATE KEY-----";
 | 
						||
        }
 | 
						||
 | 
						||
        public static void ImportPublicKeyPem(this RSA rsa, string pem)
 | 
						||
        {
 | 
						||
            var base64 = pem.Replace("-----BEGIN PUBLIC KEY-----", "")
 | 
						||
                           .Replace("-----END PUBLIC KEY-----", "")
 | 
						||
                           .Replace("\n", "");
 | 
						||
            var bytes = Convert.FromBase64String(base64);
 | 
						||
            rsa.ImportSubjectPublicKeyInfo(bytes, out _);
 | 
						||
        }
 | 
						||
 | 
						||
        public static void ImportPrivateKeyPem(this RSA rsa, string pem)
 | 
						||
        {
 | 
						||
            var base64 = pem.Replace("-----BEGIN PRIVATE KEY-----", "")
 | 
						||
                           .Replace("-----END PRIVATE KEY-----", "")
 | 
						||
                           .Replace("\n", "");
 | 
						||
            var bytes = Convert.FromBase64String(base64);
 | 
						||
            rsa.ImportPkcs8PrivateKey(bytes, out _);
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 扩展方法:导出PEM格式的私钥
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="rsa"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static string ExportRSAPrivateKeyPem(this RSA rsa)
 | 
						||
        {
 | 
						||
            var privateKey = rsa.ExportRSAPrivateKey();
 | 
						||
            //return Convert.ToBase64String(privateKey, Base64FormattingOptions.InsertLineBreaks);
 | 
						||
            return Encoding.UTF8.GetString(privateKey);
 | 
						||
            //return "-----BEGIN PRIVATE KEY-----\n" +
 | 
						||
            //    Encoding.UTF8.GetString(privateKey)
 | 
						||
            //       //Convert.ToBase64String(privateKey, Base64FormattingOptions.InsertLineBreaks) 
 | 
						||
            //       + "\n-----END PRIVATE KEY-----";
 | 
						||
            //return "-----BEGIN PRIVATE KEY-----" +
 | 
						||
            //    Encoding.UTF8.GetString(privateKey)
 | 
						||
            //       //Convert.ToBase64String(privateKey, Base64FormattingOptions.InsertLineBreaks) 
 | 
						||
            //       + "-----END PRIVATE KEY-----";
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 扩展方法:导出PEM格式的公钥
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="rsa"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static string ExportRSAPublicKeyPem(this RSA rsa)
 | 
						||
        {
 | 
						||
            var publicKey = rsa.ExportRSAPublicKey();
 | 
						||
            //return Convert.ToBase64String(publicKey, Base64FormattingOptions.InsertLineBreaks);
 | 
						||
            return Encoding.UTF8.GetString(publicKey);
 | 
						||
 | 
						||
            //return "-----BEGIN PUBLIC KEY-----\n" +
 | 
						||
            //    Encoding.UTF8.GetString(publicKey)
 | 
						||
            //       //Convert.ToBase64String(publicKey, Base64FormattingOptions.InsertLineBreaks) 
 | 
						||
            //       + "\n-----END PUBLIC KEY-----";
 | 
						||
            //return "-----BEGIN PUBLIC KEY-----" +
 | 
						||
            //    Encoding.UTF8.GetString(publicKey)
 | 
						||
            //       //Convert.ToBase64String(publicKey, Base64FormattingOptions.InsertLineBreaks) 
 | 
						||
            //       + "-----END PUBLIC KEY-----";
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 |