LMS.service/LMS.Common/RSAKey/RsaKeyPairGenerator.cs

132 lines
5.0 KiB
C#
Raw Normal View History

2024-10-13 17:04:47 +08:00
using LMS.Common.RSAKey;
using System.Security.Cryptography;
using System.Text;
namespace LMS.Common.RSAKey
{
public static class RsaKeyPairGenerator
{
/// <summary>
/// 初始化一个RSA密钥对
/// </summary>
/// <returns></returns>
public static RSAKeyGenerateModel InitRsaKey()
{
using RSACryptoServiceProvider rsa = new(2048);
string publicKeyPem = ExportPublicKeyToPem(rsa);
string privateKeyPem = ExportPrivateKeyToPem(rsa);
// 随机生成一个AES密钥
byte[] aesKey = GenerateRandomAesKey(32);
byte[] aesIv = GenerateRandomAesKey(16);
// 通过随机的密钥开始AES加密私钥
string encryptPrivateKey = AESGenerate.Encrypt(privateKeyPem, aesKey, aesIv);
return new RSAKeyGenerateModel
{
PublicKey = publicKeyPem,
EncryptedPrivateKey = encryptPrivateKey,
EncryptedKey = Convert.ToBase64String(ComplexKeyObfuscator.Obfuscate(aesKey)),
EncryptionIV = Convert.ToBase64String(ComplexKeyObfuscator.Obfuscate(aesIv))
};
}
private static byte[] GenerateRandomAesKey(int bits)
{
using var randomNumberGenerator = RandomNumberGenerator.Create();
var randomBytes = new byte[bits]; // 256 bits
randomNumberGenerator.GetBytes(randomBytes);
return randomBytes;
}
public static void GenerateRsaKeyPair()
{
using RSACryptoServiceProvider rsa = new(2048);
string publicKeyPem = ExportPublicKeyToPem(rsa);
string privateKeyPem = ExportPrivateKeyToPem(rsa);
Console.WriteLine("公钥 (PEM)\n" + publicKeyPem);
Console.WriteLine("私钥 (PEM)\n" + privateKeyPem);
Console.WriteLine();
string original = "Hello, RSA!";
var encrypted = Encrypt(publicKeyPem, original);
Console.WriteLine("Encrypted: " + encrypted);
Console.WriteLine();
var decrypted = Decrypt(privateKeyPem, encrypted);
Console.WriteLine("Decrypted: " + decrypted);
var signData = SignData(privateKeyPem, original);
Console.WriteLine("SignData: " + signData);
var isVerify = VerifySignData(publicKeyPem, original, signData);
Console.WriteLine("VerifySign: " + isVerify);
}
private static string ExportPublicKeyToPem(RSA rsa)
{
var publicKey = rsa.ExportSubjectPublicKeyInfo();
var base64 = Convert.ToBase64String(publicKey);
return $"-----BEGIN PUBLIC KEY-----\n{InsertNewLines(base64)}\n-----END PUBLIC KEY-----";
}
private static string ExportPrivateKeyToPem(RSA rsa)
{
var privateKey = rsa.ExportPkcs8PrivateKey();
var base64 = Convert.ToBase64String(privateKey);
return $"-----BEGIN PRIVATE KEY-----\n{InsertNewLines(base64)}\n-----END PRIVATE KEY-----";
}
private static string InsertNewLines(string input)
{
return string.Join("\n", Enumerable.Range(0, input.Length / 64 + 1)
.Select(i => input.Substring(i * 64, Math.Min(64, input.Length - i * 64))));
}
public static string Encrypt(string publicKeyPem, string data)
{
using (var rsa = RSA.Create())
{
rsa.ImportFromPem(publicKeyPem);
byte[] encryptedData = rsa.Encrypt(Encoding.UTF8.GetBytes(data), RSAEncryptionPadding.OaepSHA256);
return Convert.ToBase64String(encryptedData);
}
}
public static string Decrypt(string privateKeyPem, string data)
{
using (var rsa = RSA.Create())
{
rsa.ImportFromPem(privateKeyPem);
byte[] decryptedData = rsa.Decrypt(Convert.FromBase64String(data), RSAEncryptionPadding.OaepSHA256);
return Encoding.UTF8.GetString(decryptedData);
}
}
public static string SignData(string privateKeyPem, string data)
{
using (var rsa = RSA.Create())
{
rsa.ImportFromPem(privateKeyPem);
var inputBytes = Encoding.UTF8.GetBytes(data);
var resultBytes = rsa.SignData(inputBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
return Convert.ToBase64String(resultBytes);
}
}
public static bool VerifySignData(string publicKeyPem, string data, string sign)
{
using (var rsa = RSA.Create())
{
rsa.ImportFromPem(publicKeyPem);
var dataBytes = Encoding.UTF8.GetBytes(data);
var signBytes = Convert.FromBase64String(sign);
return rsa.VerifyData(dataBytes, signBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
}
}
}