A lot of works different areas... no plan

This commit is contained in:
Janus C. H. Knudsen 2025-02-16 23:39:26 +01:00
parent 087f8ce0e9
commit 1aea1e894a
16 changed files with 1433 additions and 131 deletions

View file

@ -16,6 +16,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.1" />
<PackageReference Include="npgsql" Version="9.0.2" />
<PackageReference Include="Seq.Api" Version="2024.3.0" />
<PackageReference Include="Sodium.Core" Version="1.3.5" />
</ItemGroup>
<ItemGroup>

View file

@ -0,0 +1,27 @@
namespace Core.CryptoService
{
internal class MasterKey
{
public async Task RotateMasterKey(int tenantId, string oldMasterKey, string newMasterKey)
{
// Hent alle bruger-keys for tenant
//var users = await GetTenantUsers(tenantId);
//// Dekrypter connection string med gammel master key
//var connString = DecryptWithKey(encryptedConnString, oldMasterKey);
//// Krypter med ny master key
//var newEncryptedConnString = EncryptWithKey(connString, newMasterKey);
//// Re-krypter master key for alle brugere
//foreach (var user in users)
//{
// var userKey = DeriveKeyFromPassword(user.Password);
// var newEncryptedMasterKey = EncryptWithKey(newMasterKey, userKey);
// await UpdateUserMasterKey(user.UserId, newEncryptedMasterKey);
//}
//await UpdateTenantConnectionString(tenantId, newEncryptedConnString);
}
}
}

View file

@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Core.CryptoService
{
public class SecureConnectionString
{
const string _masterKey = "5AFD74B1C26E87FE6656099E850DC67A";
public class EncryptedData
{
public string EncryptedConnectionString { get; set; }
public Dictionary<string, string> UserMasterKeys { get; set; } = new();
}
public EncryptedData EncryptConnectionString(string connectionString)
{
var encryptedConnString = EncryptWithKey(connectionString, _masterKey);
var userKeys = new Dictionary<string, string>();
return new EncryptedData
{
EncryptedConnectionString = encryptedConnString,
UserMasterKeys = userKeys
};
}
public string AddNewUser(string username, string password)
{
var userKey = DeriveKeyFromPassword(password);
var encryptedMasterKey = EncryptWithKey(_masterKey, userKey);
return encryptedMasterKey;
}
public string Decrypt(string encryptedConnString, string encryptedMasterKey, string password)
{
var userKey = DeriveKeyFromPassword(password);
var masterKey = DecryptWithKey(encryptedMasterKey, userKey);
return DecryptWithKey(encryptedConnString, masterKey);
}
private string DeriveKeyFromPassword(string password)
{
using var deriveBytes = new Rfc2898DeriveBytes(
password,
new byte[16], // Fast salt for simpelhed - i produktion bør dette være unikt per bruger
10000,
HashAlgorithmName.SHA256);
return Convert.ToBase64String(deriveBytes.GetBytes(32));
}
private string EncryptWithKey(string value, string key)
{
using var aes = Aes.Create();
var keyBytes = Convert.FromBase64String(key);
aes.Key = keyBytes;
aes.GenerateIV();
using var encryptor = aes.CreateEncryptor();
var valueBytes = Encoding.UTF8.GetBytes(value);
var encrypted = encryptor.TransformFinalBlock(valueBytes, 0, valueBytes.Length);
var result = new byte[aes.IV.Length + encrypted.Length];
Array.Copy(aes.IV, 0, result, 0, aes.IV.Length);
Array.Copy(encrypted, 0, result, aes.IV.Length, encrypted.Length);
return Convert.ToBase64String(result);
}
private string DecryptWithKey(string encryptedValue, string key)
{
var encryptedBytes = Convert.FromBase64String(encryptedValue);
using var aes = Aes.Create();
var keyBytes = Convert.FromBase64String(key);
aes.Key = keyBytes;
var iv = new byte[16];
Array.Copy(encryptedBytes, 0, iv, 0, iv.Length);
aes.IV = iv;
using var decryptor = aes.CreateDecryptor();
var decrypted = decryptor.TransformFinalBlock(
encryptedBytes,
iv.Length,
encryptedBytes.Length - iv.Length);
return Encoding.UTF8.GetString(decrypted);
}
}
}