using DigitalData.Core.Abstractions.Security; using DigitalData.Core.Security.Config; using Microsoft.Extensions.Options; using System.Security.Cryptography; namespace DigitalData.Core.Security.Cryptographer { public class RSAFactory : IRSAFactory where TRSAFactoryParams : RSAFactoryParams { protected readonly TRSAFactoryParams _params; public RSAFactory(IOptions options) => _params = options.Value; public string CreatePrivateKeyPem(int? keySizeInBits = null) => RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportRSAPrivateKeyPem(); public string CreateEncryptedPrivateKeyPem( PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null, HashAlgorithmName? hashAlgorithmName = null, int? iterationCount = null, int? keySizeInBits = null, string? password = null) { password ??= _params.PbePassword; var pbeParameters = pbeEncryptionAlgorithm is null && hashAlgorithmName is null && iterationCount is null ? new PbeParameters( pbeEncryptionAlgorithm ?? _params.PbeEncryptionAlgorithm, hashAlgorithmName ?? _params.PbeHashAlgorithmName, iterationCount ?? _params.PbeIterationCount) : _params.PbeParameters; var encryptedPrivateKey = RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters); var pemChars = PemEncoding.Write(_params.EncryptedPrivateKeyPemLabel, encryptedPrivateKey); return new string(pemChars); } public string CreateEncryptedPrivateKeyPem( PbeParameters pbeParameters, int? keySizeInBits = null, string? password = null) { password ??= _params.PbePassword; var encryptedPrivateKey = RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters); var pemChars = PemEncoding.Write(_params.EncryptedPrivateKeyPemLabel, encryptedPrivateKey); return new string(pemChars); } } }