Compare commits
19 Commits
4a64a31d47
...
3ffdd49a47
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ffdd49a47 | ||
|
|
609cd29dc5 | ||
|
|
cc3d1f58d3 | ||
|
|
c03f39c1a9 | ||
|
|
750f7bc20c | ||
|
|
65989b23b3 | ||
|
|
c895d2df0e | ||
|
|
0c451cb834 | ||
|
|
9396f48f46 | ||
|
|
1a941b4728 | ||
|
|
c6942164e2 | ||
|
|
343560ed62 | ||
|
|
6873bac8a1 | ||
|
|
09406ca505 | ||
|
|
3aa5ad782f | ||
|
|
5991444efd | ||
|
|
f720ea9cd6 | ||
|
|
a4b96c2f3e | ||
|
|
816d5835f1 |
@@ -0,0 +1,9 @@
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IAsymCryptService<TParams> : IRSAFactory<TParams>
|
||||
{
|
||||
IRSADecryptor this[string key] { get; }
|
||||
|
||||
bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface ICryptFactory
|
||||
{
|
||||
int KeySizeInBits { get; init; }
|
||||
|
||||
string PbePassword { init; }
|
||||
|
||||
PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; }
|
||||
|
||||
HashAlgorithmName PbeHashAlgorithmName { get; init; }
|
||||
|
||||
int PbeIterationCount { get; init; }
|
||||
|
||||
PbeParameters PbeParameters { get; }
|
||||
|
||||
string EncryptedPrivateKeyPemLabel { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the formatter function for generating RSA key names.
|
||||
/// This formatter takes an issuer, audience, isPrivate, and optional version and separator
|
||||
/// to produce a formatted string used for the key naming convention.
|
||||
/// </summary>
|
||||
/// <param name="issuer">A string representing the issuer of the key. It should not contain invalid file name characters or the separator.</param>
|
||||
/// <param name="audience">A string representing the audience for which the key is intended. It should not contain invalid file name characters or the separator.</param>
|
||||
/// <param name="isPrivate">An bool to check if the key is private.</param>
|
||||
/// <param name="version">An instance of the <see cref="Version?"/> interface, which is used to keep the version of Pbe password.</param>
|
||||
/// <param name="separator">An optional string separator used to separate the issuer and audience. The default is "-_-". It should not be included in the issuer or audience strings.</param>
|
||||
/// <returns>A formatted string combining the issuer, audience, and separator, which adheres to valid file naming rules.</returns>
|
||||
/// <exception cref="ArgumentException">Thrown when the issuer, audience, or separator contains invalid characters or when the separator is present within the issuer or audience.</exception>
|
||||
Func<string, string, bool, Version?, string?, string> RSAKeyNameFormatter { get; }
|
||||
|
||||
string CreateRSAPrivateKeyPem(int? keySizeInBits = null);
|
||||
|
||||
string CreateEncryptedPrivateKeyPem(
|
||||
int? keySizeInBits = null,
|
||||
string? password = null,
|
||||
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
|
||||
HashAlgorithmName? hashAlgorithmName = null,
|
||||
int? iterationCount = null);
|
||||
|
||||
IRSADecryptor this[string key] { get; }
|
||||
|
||||
bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor);
|
||||
}
|
||||
}
|
||||
18
DigitalData.Core.Abstractions/Security/IRSAFactory.cs
Normal file
18
DigitalData.Core.Abstractions/Security/IRSAFactory.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IRSAFactory<TParams>
|
||||
{
|
||||
string CreateRSAPrivateKeyPem(int? keySizeInBits = null);
|
||||
|
||||
string CreateEncryptedPrivateKeyPem(
|
||||
int? keySizeInBits = null,
|
||||
string? password = null,
|
||||
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
|
||||
HashAlgorithmName? hashAlgorithmName = null,
|
||||
int? iterationCount = null);
|
||||
|
||||
Task<IRSADecryptor> ReadRSADecryptorAsync(string path, Version? version = null, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ namespace DigitalData.Core.Client
|
||||
{
|
||||
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
|
||||
|
||||
var flagParams = queryParams.Where(param => param.Value is null).Select(param => HttpUtility.UrlEncode(param.Key));
|
||||
var flagParams = queryParams.Where(param => param.Value is null).Select(param => param.Key);
|
||||
|
||||
var valueParams = queryParams.Where(param => param.Value is not null);
|
||||
|
||||
@@ -94,12 +94,12 @@ namespace DigitalData.Core.Client
|
||||
query[param.Key] = param.Value switch
|
||||
{
|
||||
bool b => b.ToString().ToLower(),
|
||||
_ => HttpUtility.UrlEncode(param.Value.ToString())
|
||||
_ => param.Value.ToString()
|
||||
};
|
||||
|
||||
var flagQuery = string.Join(QUERY_SEPARATOR, flagParams);
|
||||
|
||||
uriBuilder.Query = string.Join(QUERY_SEPARATOR, query.ToString(), flagQuery);
|
||||
if (flagParams.Any())
|
||||
uriBuilder.Query = string.Join(QUERY_SEPARATOR, query.ToString(), string.Join(QUERY_SEPARATOR, flagParams));
|
||||
else uriBuilder.Query = query.ToString();
|
||||
}
|
||||
|
||||
var requestUri = uriBuilder.Uri;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Description>This package provides HTTP client extension methods for the DigitalData.Core library, offering simplified and asynchronous methods for fetching and handling HTTP responses. It includes utility methods for sending GET requests, reading response content as text or JSON, and deserializing JSON into dynamic or strongly-typed objects using Newtonsoft.Json. These extensions facilitate efficient and easy-to-read HTTP interactions in client applications.</Description>
|
||||
<PackageId>DigitalData.Core.Client</PackageId>
|
||||
<Version>2.0.1</Version>
|
||||
<Version>2.0.3</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>Digital Data GmbH</Product>
|
||||
@@ -15,8 +15,8 @@
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core http client json serilization</PackageTags>
|
||||
<AssemblyVersion>2.0.1</AssemblyVersion>
|
||||
<FileVersion>2.0.1</FileVersion>
|
||||
<AssemblyVersion>2.0.3</AssemblyVersion>
|
||||
<FileVersion>2.0.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -12,13 +12,7 @@ namespace DigitalData.Core.Security.Extensions
|
||||
rsa.ImportFromPem(pem);
|
||||
return rsa;
|
||||
}
|
||||
|
||||
public static IRSADecryptor GetRSADecryptor(this ICryptFactory factory, string issuer, string audience, Version? version = null, string? seperator = null)
|
||||
=> factory[factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator)];
|
||||
|
||||
public static bool TryGetRSADecryptor(this ICryptFactory factory, string issuer, string audience, out IRSADecryptor? decryptor, Version? version = null, string? seperator = null)
|
||||
=> factory.TryGetRSADecryptor(factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator), out decryptor);
|
||||
|
||||
|
||||
private static string CreatePath(string filename, string? directory = null)
|
||||
{
|
||||
directory ??= Environment.CurrentDirectory;
|
||||
|
||||
7
DigitalData.Core.Security/AsymCryptParams.cs
Normal file
7
DigitalData.Core.Security/AsymCryptParams.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public class AsymCryptParams : RSAFactoryParams
|
||||
{
|
||||
public IEnumerable<ReadOrCreateDirectory> ReadOrCreateDirs { get; init; } = new List<ReadOrCreateDirectory>();
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,18 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public class CryptFactory : RSAFactory, ICryptFactory
|
||||
public class AsymCryptService<TAsymCryptParams> : RSAFactory<TAsymCryptParams>, IAsymCryptService<TAsymCryptParams>, IRSAFactory<TAsymCryptParams> where TAsymCryptParams : AsymCryptParams
|
||||
{
|
||||
private readonly IDictionary<string, IRSADecryptor> _decryptors;
|
||||
private readonly Dictionary<string, IRSADecryptor> _decryptors;
|
||||
|
||||
public IRSADecryptor this[string key] { get => _decryptors[key]; set => _decryptors[key] = value; }
|
||||
|
||||
public Func<string, string, bool, Version?, string?, string> RSAKeyNameFormatter { get; }
|
||||
|
||||
public CryptFactory(ILogger<CryptFactory> logger, IDictionary<string, IRSADecryptor> decryptors, Func<string, string, bool, Version?, string?, string> rsaKeyNameFormatter) : base()
|
||||
public AsymCryptService(IOptions<TAsymCryptParams> options, ILogger<AsymCryptService<TAsymCryptParams>>? logger = null) : base(options)
|
||||
{
|
||||
_decryptors = decryptors ?? new Dictionary<string, IRSADecryptor>();
|
||||
|
||||
RSAKeyNameFormatter = rsaKeyNameFormatter;
|
||||
|
||||
_decryptors = new();
|
||||
logger?.LogInformation("Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy"));
|
||||
}
|
||||
|
||||
12
DigitalData.Core.Security/CryptographicKeyType.cs
Normal file
12
DigitalData.Core.Security/CryptographicKeyType.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public enum CryptographicKeyType
|
||||
{
|
||||
PrivateKey,
|
||||
EncryptedPrivateKey,
|
||||
PublicKey
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,41 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public static class DIExtensions
|
||||
{
|
||||
public static IServiceCollection AddSecurity(this IServiceCollection services)
|
||||
private static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services)
|
||||
where TAsymCryptParams : AsymCryptParams
|
||||
{
|
||||
services.TryAddScoped<ICryptFactory, CryptFactory>();
|
||||
|
||||
services.TryAddScoped<IAsymCryptService<TAsymCryptParams>, AsymCryptService<TAsymCryptParams>>();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services, IConfigurationSection section)
|
||||
where TAsymCryptParams : AsymCryptParams
|
||||
=> services.Configure<TAsymCryptParams>(section).AddAsymCryptService<TAsymCryptParams>();
|
||||
|
||||
public static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services, TAsymCryptParams param)
|
||||
where TAsymCryptParams : AsymCryptParams
|
||||
=> services.AddSingleton(Options.Create(param)).AddAsymCryptService<TAsymCryptParams>();
|
||||
|
||||
private static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services)
|
||||
where TRSAFactoryParams : RSAFactoryParams
|
||||
{
|
||||
services.TryAddScoped<IRSAFactory<TRSAFactoryParams>, RSAFactory<TRSAFactoryParams>>();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services, IConfigurationSection section)
|
||||
where TRSAFactoryParams : RSAFactoryParams
|
||||
=> services.Configure<TRSAFactoryParams>(section).AddRSAFactory<TRSAFactoryParams>();
|
||||
|
||||
public static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services, TRSAFactoryParams param)
|
||||
where TRSAFactoryParams : RSAFactoryParams
|
||||
=> services.AddSingleton(Options.Create(param)).AddRSAFactory<TRSAFactoryParams>();
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,10 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Abstractions\DigitalData.Core.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.Core.Security.Extensions\DigitalData.Core.Security.Extensions.csproj" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
@@ -11,6 +12,39 @@ namespace DigitalData.Core.Security
|
||||
|
||||
protected virtual RSA RSA { get; } = RSA.Create();
|
||||
|
||||
public string? Issuer { get; init; }
|
||||
|
||||
public string? Audience { get; init; }
|
||||
|
||||
private DateOnly? _expiration;
|
||||
|
||||
public DateOnly? Expiration
|
||||
{
|
||||
get => _expiration;
|
||||
init
|
||||
{
|
||||
|
||||
if (value <= DateOnly.FromDateTime(DateTime.Now))
|
||||
throw new InvalidOperationException($"Cryptographer expiration date has already passed. Cryptographer: {JsonSerializer.Serialize(this)}");
|
||||
|
||||
_expiration = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Version? _version;
|
||||
|
||||
public Version? Version
|
||||
{
|
||||
get => _version;
|
||||
init
|
||||
{
|
||||
if (value != Secrets.Version)
|
||||
throw new InvalidOperationException($"Cryptographer version ({value}) does not match the expected version ({Secrets.Version}). Cryptographer: {JsonSerializer.Serialize(this)}");
|
||||
|
||||
_version = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal RSACryptographer() { }
|
||||
}
|
||||
}
|
||||
@@ -1,89 +1,21 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public class RSAFactory
|
||||
public class RSAFactory<TRSAFactoryParams> : IRSAFactory<TRSAFactoryParams> where TRSAFactoryParams : RSAFactoryParams
|
||||
{
|
||||
private static readonly Lazy<RSAFactory> LazyInstance = new(() => new());
|
||||
private static readonly Lazy<RSAFactory<RSAFactoryParams>> LazyInstance = new(() => new(Options.Create<RSAFactoryParams>(new())));
|
||||
|
||||
public static RSAFactory Static => LazyInstance.Value;
|
||||
public static RSAFactory<RSAFactoryParams> Static => LazyInstance.Value;
|
||||
|
||||
public static readonly string DefaultEncryptedPrivateKeyFileTag = "enc-private";
|
||||
|
||||
public static readonly string DefaultPrivateKeyFileTag = "private";
|
||||
|
||||
public static readonly string DefaultPublicKeyFileTag = "public";
|
||||
|
||||
public static readonly IEnumerable<string> KeyFileTags = new string[] { DefaultEncryptedPrivateKeyFileTag, DefaultPrivateKeyFileTag, DefaultPublicKeyFileTag };
|
||||
|
||||
private static readonly Lazy<IEnumerable<string>> LazyLowerFileTags = new(() => KeyFileTags.Select(tag => tag.ToLower()));
|
||||
|
||||
public static readonly string DefaultRSAKeyNameSeparator = "-_-";
|
||||
|
||||
//TODO: make the validation using regex
|
||||
public static string DefaultRSAKeyNameFormatter(string issuer, string audience, bool isPrivate = true, Version? passwordVersion = null, string? separator = null)
|
||||
{
|
||||
separator ??= DefaultRSAKeyNameSeparator;
|
||||
|
||||
void ValidateForbidden(string value, string paramName)
|
||||
{
|
||||
if (Path.GetInvalidFileNameChars().Any(value.Contains) || LazyLowerFileTags.Value.Any(tag => value.ToLower().Contains(tag)))
|
||||
throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains forbidden characters that are not allowed in file naming.", paramName);
|
||||
}
|
||||
|
||||
static void ValidateSeparator(string value, string paramName, string separator)
|
||||
{
|
||||
if (value.Contains(separator))
|
||||
throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains separator characters ({separator}) that are not allowed in file naming.", paramName);
|
||||
}
|
||||
|
||||
ValidateForbidden(issuer, nameof(issuer));
|
||||
ValidateForbidden(audience, nameof(audience));
|
||||
ValidateForbidden(separator, nameof(separator));
|
||||
|
||||
ValidateSeparator(issuer, nameof(issuer), separator);
|
||||
ValidateSeparator(audience, nameof(audience), separator);
|
||||
|
||||
var sb = new StringBuilder(issuer.Length + audience.Length + separator.Length * 2 + 20);
|
||||
sb.Append(issuer).Append(separator).Append(audience).Append(separator);
|
||||
|
||||
if (passwordVersion is null && isPrivate)
|
||||
sb.Append(DefaultPrivateKeyFileTag);
|
||||
else if (isPrivate)
|
||||
sb.Append(DefaultEncryptedPrivateKeyFileTag).Append(separator).Append(passwordVersion);
|
||||
else if (passwordVersion is null)
|
||||
sb.Append(DefaultPublicKeyFileTag);
|
||||
else
|
||||
sb.Append(DefaultPublicKeyFileTag).Append(separator).Append(passwordVersion);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public int KeySizeInBits { get; init; } = 2048;
|
||||
|
||||
public string PbePassword { private get; init; } = Secrets.PBE_PASSWORD;
|
||||
|
||||
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = PbeEncryptionAlgorithm.Aes256Cbc;
|
||||
|
||||
public HashAlgorithmName PbeHashAlgorithmName { get; init; } = HashAlgorithmName.SHA256;
|
||||
|
||||
public int PbeIterationCount { get; init; } = 100_000;
|
||||
|
||||
private readonly Lazy<PbeParameters> _lazyPbeParameters;
|
||||
|
||||
public PbeParameters PbeParameters => _lazyPbeParameters.Value;
|
||||
|
||||
public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY";
|
||||
|
||||
internal RSAFactory()
|
||||
{
|
||||
_lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount));
|
||||
}
|
||||
protected readonly TRSAFactoryParams _params;
|
||||
|
||||
public RSAFactory(IOptions<TRSAFactoryParams> options) => _params = options.Value;
|
||||
|
||||
public string CreateRSAPrivateKeyPem(int? keySizeInBits = null)
|
||||
=> RSA.Create(keySizeInBits ?? KeySizeInBits).ExportRSAPrivateKeyPem();
|
||||
=> RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportRSAPrivateKeyPem();
|
||||
|
||||
public string CreateEncryptedPrivateKeyPem(
|
||||
int? keySizeInBits = null,
|
||||
@@ -92,18 +24,18 @@ namespace DigitalData.Core.Security
|
||||
HashAlgorithmName? hashAlgorithmName = null,
|
||||
int? iterationCount = null)
|
||||
{
|
||||
password ??= PbePassword;
|
||||
password ??= _params.PbePassword;
|
||||
|
||||
var pbeParameters = (pbeEncryptionAlgorithm is null && hashAlgorithmName is null && iterationCount is null)
|
||||
? new PbeParameters(
|
||||
pbeEncryptionAlgorithm ?? PbeEncryptionAlgorithm,
|
||||
hashAlgorithmName ?? PbeHashAlgorithmName,
|
||||
iterationCount ?? PbeIterationCount)
|
||||
: PbeParameters;
|
||||
pbeEncryptionAlgorithm ?? _params.PbeEncryptionAlgorithm,
|
||||
hashAlgorithmName ?? _params.PbeHashAlgorithmName,
|
||||
iterationCount ?? _params.PbeIterationCount)
|
||||
: _params.PbeParameters;
|
||||
|
||||
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
|
||||
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
|
||||
|
||||
var pemChars = PemEncoding.Write(EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
|
||||
var pemChars = PemEncoding.Write(_params.EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
|
||||
|
||||
return new string(pemChars);
|
||||
}
|
||||
|
||||
34
DigitalData.Core.Security/RSAFactoryParams.cs
Normal file
34
DigitalData.Core.Security/RSAFactoryParams.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public class RSAFactoryParams
|
||||
{
|
||||
public string EncryptedPrivateKeyFileTag { get; init; } = "enc-private";
|
||||
|
||||
public string PrivateKeyFileTag { get; init; } = "private";
|
||||
|
||||
public string PublicKeyFileTag { get; init; } = "public";
|
||||
|
||||
public string RSAKeyNameSeparator { get; init; } = "-_-";
|
||||
|
||||
public int KeySizeInBits { get; init; } = 2048;
|
||||
|
||||
public string PbePassword { internal get; init; } = Secrets.PBE_PASSWORD;
|
||||
|
||||
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = PbeEncryptionAlgorithm.Aes256Cbc;
|
||||
|
||||
public HashAlgorithmName PbeHashAlgorithmName { get; init; } = HashAlgorithmName.SHA256;
|
||||
|
||||
public int PbeIterationCount { get; init; } = 100_000;
|
||||
|
||||
public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY";
|
||||
|
||||
private readonly Lazy<PbeParameters> _lazyPbeParameters;
|
||||
|
||||
public PbeParameters PbeParameters => _lazyPbeParameters.Value;
|
||||
|
||||
public RSAFactoryParams()
|
||||
=> _lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount));
|
||||
}
|
||||
}
|
||||
9
DigitalData.Core.Security/ReadOrCreateDirectory.cs
Normal file
9
DigitalData.Core.Security/ReadOrCreateDirectory.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public class ReadOrCreateDirectory
|
||||
{
|
||||
public required string Dir { get; init; }
|
||||
|
||||
public IEnumerable<string> ReadOrCreateFiles { get; init; } = new List<string>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user