132 lines
5.0 KiB
C#
132 lines
5.0 KiB
C#
|
|
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);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|