108 lines
3.2 KiB
C#
108 lines
3.2 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
namespace SNote.Server.Security;
|
|
|
|
public class RsaKeyManager
|
|
{
|
|
private readonly string _publicKeyPath;
|
|
private readonly string _privateKeyPath;
|
|
private RSA? _privateKeyRsa;
|
|
private RSA? _publicKeyRsa;
|
|
private string _publicKeyPem = string.Empty;
|
|
private string _privateKeyPem = string.Empty;
|
|
|
|
public RsaKeyManager(IConfiguration configuration)
|
|
{
|
|
_publicKeyPath = Path.Combine(AppContext.BaseDirectory, "snote-public.pem");
|
|
_privateKeyPath = Path.Combine(AppContext.BaseDirectory, "snote-private.pem");
|
|
|
|
var configPublicKey = configuration["Sync:PublicKey"];
|
|
var configPrivateKey = configuration["Sync:PrivateKey"];
|
|
|
|
if (!string.IsNullOrEmpty(configPublicKey) && !string.IsNullOrEmpty(configPrivateKey))
|
|
{
|
|
_publicKeyPem = configPublicKey;
|
|
_privateKeyPem = configPrivateKey;
|
|
InitializeKeys();
|
|
}
|
|
else
|
|
{
|
|
LoadOrGenerateKeys();
|
|
}
|
|
}
|
|
|
|
private void InitializeKeys()
|
|
{
|
|
try
|
|
{
|
|
_publicKeyRsa = RSA.Create();
|
|
_publicKeyRsa.ImportFromPem(_publicKeyPem);
|
|
|
|
_privateKeyRsa = RSA.Create();
|
|
_privateKeyRsa.ImportFromPem(_privateKeyPem);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"[RsaKeyManager] Error initializing configured keys: {ex.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private void LoadOrGenerateKeys()
|
|
{
|
|
if (File.Exists(_privateKeyPath) && File.Exists(_publicKeyPath))
|
|
{
|
|
try
|
|
{
|
|
_publicKeyPem = File.ReadAllText(_publicKeyPath);
|
|
_privateKeyPem = File.ReadAllText(_privateKeyPath);
|
|
InitializeKeys();
|
|
Console.WriteLine("[RsaKeyManager] Loaded existing RSA keys from disk.");
|
|
return;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"[RsaKeyManager] Error loading RSA keys from disk: {ex.Message}. Re-generating.");
|
|
}
|
|
}
|
|
|
|
// Generate new keypair
|
|
Console.WriteLine("[RsaKeyManager] Generating new secure 2048-bit RSA keypair...");
|
|
using var rsa = RSA.Create(2048);
|
|
|
|
_publicKeyPem = rsa.ExportSubjectPublicKeyInfoPem();
|
|
_privateKeyPem = rsa.ExportPkcs8PrivateKeyPem();
|
|
|
|
File.WriteAllText(_publicKeyPath, _publicKeyPem);
|
|
File.WriteAllText(_privateKeyPath, _privateKeyPem);
|
|
|
|
InitializeKeys();
|
|
Console.WriteLine("[RsaKeyManager] Secure RSA keypair generated and saved to disk.");
|
|
}
|
|
|
|
public RSA GetPrivateKey()
|
|
{
|
|
if (_privateKeyRsa == null) throw new InvalidOperationException("Private key is not loaded.");
|
|
return _privateKeyRsa;
|
|
}
|
|
|
|
public RSA GetPublicKey()
|
|
{
|
|
if (_publicKeyRsa == null) throw new InvalidOperationException("Public key is not loaded.");
|
|
return _publicKeyRsa;
|
|
}
|
|
|
|
public string GetPublicKeyPem()
|
|
{
|
|
return _publicKeyPem;
|
|
}
|
|
|
|
public string GetPrivateKeyPem()
|
|
{
|
|
return _privateKeyPem;
|
|
}
|
|
}
|