using System.Security.Cryptography;
using System.Text;
using Xunit.Abstractions;
namespace xUnit.Tests
{
/// <summary>
///
/// </summary>
public class RsaKeyPairGenerator
{
private readonly ITestOutputHelper _testOutputHelper;
/// <summary>
///
/// </summary>
/// <param name="testOutputHelper"></param>
public RsaKeyPairGenerator(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}
/// <summary>
///
/// </summary>
[Fact]
public void GenerateRsaKeyPair()
{
// 1. 生成RSA密钥对
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024))
{
// 1.获取公钥和私钥
byte[] publicKeyBytes = rsa.ExportSubjectPublicKeyInfo(); // 公钥X.509格式生成
byte[] privateKeyBytes = rsa.ExportPkcs8PrivateKey(); // 私钥以PKCS#8格式生成
string publicKey = Convert.ToBase64String(publicKeyBytes);
var privateKey = Convert.ToBase64String(privateKeyBytes);
_testOutputHelper.WriteLine("公钥:" + publicKey);
_testOutputHelper.WriteLine("私钥:" + privateKey);
// 2.加密
string original = "Hello, RSA!";
var encrypted = Encrypt(publicKey, original);
_testOutputHelper.WriteLine("Encrypted: " + encrypted);
// 3. 解密
var decrypted = Decrypt(privateKey, encrypted);
_testOutputHelper.WriteLine("Decrypted: " + decrypted);
// 4.签名
var signData = SignData(privateKey, original);
_testOutputHelper.WriteLine("SignData: " + signData);
// 5.验证签名
var isVerify = VerifySignData(publicKey, original, signData);
_testOutputHelper.WriteLine("VerifySign: " + isVerify);
}
}
/// <summary>
/// 加密
/// </summary>
/// <param name="publicKey"></param>
/// <param name="data"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public string Encrypt(string publicKey, string data)
{
var publicKeyBytes = Convert.FromBase64String(publicKey);
using (var rsa = System.Security.Cryptography.RSA.Create())
{
rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out int bytesRead);
// 使用公钥加密数据(这里使用PKCS#1 v1.5填充)
byte[] encryptedData = rsa.Encrypt(Encoding.UTF8.GetBytes(data), RSAEncryptionPadding.Pkcs1);
// 输出加密后的数据(通常为Base64编码)
return Convert.ToBase64String(encryptedData);
}
}
/// <summary>
/// 解密
/// </summary>
/// <param name="privateKey"></param>
/// <param name="data"></param>
/// <returns></returns>
public string Decrypt(string privateKey, string data)
{
var privateKeyBytes = Convert.FromBase64String(privateKey);
using (var rsa = System.Security.Cryptography.RSA.Create())
{
rsa.ImportPkcs8PrivateKey(privateKeyBytes, out int bytesRead);
return Encoding.UTF8.GetString(rsa.Decrypt(Convert.FromBase64String(data), System.Security.Cryptography.RSAEncryptionPadding.Pkcs1));
}
}
/// <summary>
/// 生成数据签名
/// </summary>
/// <param name="privateKey"></param>
/// <param name="data"></param>
/// <returns></returns>
public string SignData(string privateKey, string data)
{
var privateKeyBytes = Convert.FromBase64String(privateKey);
using (var rsa = System.Security.Cryptography.RSA.Create())
{
rsa.ImportPkcs8PrivateKey(privateKeyBytes, out int bytesRead);
var inputBytes = Encoding.UTF8.GetBytes(data);
var resultBytes = rsa.SignData(inputBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
return Convert.ToBase64String(resultBytes);
}
}
/// <summary>
/// 验证签名
/// </summary>
/// <param name="publicKey"></param>
/// <param name="data"></param>
/// <param name="sign"></param>
/// <returns></returns>
public bool VerifySignData(string publicKey, string data, string sign)
{
var publicKeyBytes = Convert.FromBase64String(publicKey);
using (var rsa = System.Security.Cryptography.RSA.Create())
{
rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out int bytesRead);
var dataBytes = Encoding.UTF8.GetBytes(data);
var singBytes = Convert.FromBase64String(sign);
var result = rsa.VerifyData(dataBytes, singBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
return result;
}
}
}
}