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); } /// /// 使用RSA私钥对数据进行签名 /// 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); } } /// /// 使用RSA公钥验证签名 /// 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 _); } /// /// 扩展方法:导出PEM格式的私钥 /// /// /// 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-----"; } /// /// 扩展方法:导出PEM格式的公钥 /// /// /// 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-----"; } } }