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-----";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|