Fingent-Security-Encryption 1.0.1

dotnet add package Fingent-Security-Encryption --version 1.0.1
                    
NuGet\Install-Package Fingent-Security-Encryption -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Fingent-Security-Encryption" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Fingent-Security-Encryption" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Fingent-Security-Encryption" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Fingent-Security-Encryption --version 1.0.1
                    
#r "nuget: Fingent-Security-Encryption, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Fingent-Security-Encryption@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Fingent-Security-Encryption&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Fingent-Security-Encryption&version=1.0.1
                    
Install as a Cake Tool

Fingent Security Encryption

A lightweight and extensible helper library for handling encryption and decryption in .NET applications. Provides simple APIs to protect sensitive data using industry-standard algorithms, making it easy to secure application secrets, files, and user information.

🚀 Features

  • AES Encryption: Industry-standard AES-256 encryption for maximum security
  • RSA Encryption: Asymmetric encryption for secure key exchange and digital signatures
  • Hash Functions: SHA-256, SHA-512, and other cryptographic hash algorithms
  • Key Management: Secure key generation, storage, and rotation
  • File Encryption: Encrypt and decrypt files and streams
  • Password Hashing: Secure password hashing with salt using bcrypt/PBKDF2
  • Digital Signatures: Create and verify digital signatures
  • Base64 Encoding: Safe encoding for encrypted data transmission

📦 Installation

dotnet add package Fingent-Security-Encryption

🔧 Dependencies

  • .NET 8.0
  • Microsoft.Extensions.Options 8.0.2

💻 Usage

Basic Setup

// Program.cs or Startup.cs
services.AddEncryptionServices(options =>
{
    options.DefaultEncryptionKey = "your-32-character-key-here-123456";
    options.KeyDerivationIterations = 10000;
    options.EnableKeyRotation = true;
});

Configuration

{
  "EncryptionSettings": {
    "DefaultEncryptionKey": "your-32-character-key-here-123456",
    "KeyDerivationIterations": 10000,
    "EnableKeyRotation": true,
    "HashAlgorithm": "SHA256",
    "EncryptionAlgorithm": "AES256"
  }
}

AES String Encryption

public class DataProtectionService
{
    private readonly IEncryptionService _encryptionService;
    private readonly ILogger<DataProtectionService> _logger;
    
    public DataProtectionService(IEncryptionService encryptionService, ILogger<DataProtectionService> logger)
    {
        _encryptionService = encryptionService;
        _logger = logger;
    }
    
    public async Task<string> ProtectSensitiveDataAsync(string sensitiveData)
    {
        try
        {
            var encryptedData = await _encryptionService.EncryptStringAsync(sensitiveData);
            _logger.LogInformation("Sensitive data encrypted successfully");
            return encryptedData;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to encrypt sensitive data");
            throw;
        }
    }
    
    public async Task<string> UnprotectSensitiveDataAsync(string encryptedData)
    {
        try
        {
            var decryptedData = await _encryptionService.DecryptStringAsync(encryptedData);
            _logger.LogInformation("Sensitive data decrypted successfully");
            return decryptedData;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to decrypt sensitive data");
            throw;
        }
    }
}

File Encryption

public class FileEncryptionService
{
    private readonly IEncryptionService _encryptionService;
    private readonly ILogger<FileEncryptionService> _logger;
    
    public FileEncryptionService(IEncryptionService encryptionService, ILogger<FileEncryptionService> logger)
    {
        _encryptionService = encryptionService;
        _logger = logger;
    }
    
    public async Task<string> EncryptFileAsync(string inputFilePath, string outputFilePath = null)
    {
        outputFilePath ??= inputFilePath + ".encrypted";
        
        try
        {
            using var inputStream = File.OpenRead(inputFilePath);
            using var outputStream = File.Create(outputFilePath);
            
            await _encryptionService.EncryptStreamAsync(inputStream, outputStream);
            
            _logger.LogInformation("File encrypted: {InputFile} -> {OutputFile}", inputFilePath, outputFilePath);
            return outputFilePath;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to encrypt file: {FilePath}", inputFilePath);
            throw;
        }
    }
    
    public async Task<string> DecryptFileAsync(string encryptedFilePath, string outputFilePath = null)
    {
        outputFilePath ??= encryptedFilePath.Replace(".encrypted", "");
        
        try
        {
            using var inputStream = File.OpenRead(encryptedFilePath);
            using var outputStream = File.Create(outputFilePath);
            
            await _encryptionService.DecryptStreamAsync(inputStream, outputStream);
            
            _logger.LogInformation("File decrypted: {InputFile} -> {OutputFile}", encryptedFilePath, outputFilePath);
            return outputFilePath;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to decrypt file: {FilePath}", encryptedFilePath);
            throw;
        }
    }
    
    public async Task<byte[]> EncryptBytesAsync(byte[] data)
    {
        using var inputStream = new MemoryStream(data);
        using var outputStream = new MemoryStream();
        
        await _encryptionService.EncryptStreamAsync(inputStream, outputStream);
        return outputStream.ToArray();
    }
    
    public async Task<byte[]> DecryptBytesAsync(byte[] encryptedData)
    {
        using var inputStream = new MemoryStream(encryptedData);
        using var outputStream = new MemoryStream();
        
        await _encryptionService.DecryptStreamAsync(inputStream, outputStream);
        return outputStream.ToArray();
    }
}

Password Hashing and Verification

public class PasswordSecurityService
{
    private readonly IPasswordHasher _passwordHasher;
    private readonly ILogger<PasswordSecurityService> _logger;
    
    public PasswordSecurityService(IPasswordHasher passwordHasher, ILogger<PasswordSecurityService> logger)
    {
        _passwordHasher = passwordHasher;
        _logger = logger;
    }
    
    public async Task<string> HashPasswordAsync(string password)
    {
        try
        {
            var hashedPassword = await _passwordHasher.HashPasswordAsync(password);
            _logger.LogInformation("Password hashed successfully");
            return hashedPassword;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to hash password");
            throw;
        }
    }
    
    public async Task<bool> VerifyPasswordAsync(string password, string hashedPassword)
    {
        try
        {
            var isValid = await _passwordHasher.VerifyPasswordAsync(password, hashedPassword);
            _logger.LogInformation("Password verification completed: {Result}", isValid ? "Valid" : "Invalid");
            return isValid;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to verify password");
            throw;
        }
    }
    
    public async Task<PasswordStrengthResult> EvaluatePasswordStrengthAsync(string password)
    {
        var result = new PasswordStrengthResult();
        
        // Check length
        result.HasMinimumLength = password.Length >= 8;
        result.HasMaximumLength = password.Length <= 128;
        
        // Check character types
        result.HasUppercase = password.Any(char.IsUpper);
        result.HasLowercase = password.Any(char.IsLower);
        result.HasDigits = password.Any(char.IsDigit);
        result.HasSpecialCharacters = password.Any(c => !char.IsLetterOrDigit(c));
        
        // Calculate strength score
        var score = 0;
        if (result.HasMinimumLength) score += 2;
        if (result.HasUppercase) score += 1;
        if (result.HasLowercase) score += 1;
        if (result.HasDigits) score += 1;
        if (result.HasSpecialCharacters) score += 2;
        if (password.Length >= 12) score += 1;
        
        result.Strength = score switch
        {
            >= 7 => PasswordStrength.VeryStrong,
            >= 5 => PasswordStrength.Strong,
            >= 3 => PasswordStrength.Medium,
            >= 1 => PasswordStrength.Weak,
            _ => PasswordStrength.VeryWeak
        };
        
        result.Score = score;
        return result;
    }
}

public class PasswordStrengthResult
{
    public bool HasMinimumLength { get; set; }
    public bool HasMaximumLength { get; set; }
    public bool HasUppercase { get; set; }
    public bool HasLowercase { get; set; }
    public bool HasDigits { get; set; }
    public bool HasSpecialCharacters { get; set; }
    public PasswordStrength Strength { get; set; }
    public int Score { get; set; }
    public bool IsValid => HasMinimumLength && HasMaximumLength && Strength >= PasswordStrength.Medium;
}

public enum PasswordStrength
{
    VeryWeak,
    Weak,
    Medium,
    Strong,
    VeryStrong
}

RSA Encryption for Key Exchange

public class AsymmetricEncryptionService
{
    private readonly IRsaEncryptionService _rsaService;
    private readonly ILogger<AsymmetricEncryptionService> _logger;
    
    public AsymmetricEncryptionService(IRsaEncryptionService rsaService, ILogger<AsymmetricEncryptionService> logger)
    {
        _rsaService = rsaService;
        _logger = logger;
    }
    
    public async Task<RsaKeyPair> GenerateKeyPairAsync(int keySize = 2048)
    {
        try
        {
            var keyPair = await _rsaService.GenerateKeyPairAsync(keySize);
            _logger.LogInformation("RSA key pair generated with key size: {KeySize}", keySize);
            return keyPair;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to generate RSA key pair");
            throw;
        }
    }
    
    public async Task<string> EncryptWithPublicKeyAsync(string data, string publicKey)
    {
        try
        {
            var encryptedData = await _rsaService.EncryptAsync(data, publicKey);
            _logger.LogInformation("Data encrypted with RSA public key");
            return encryptedData;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to encrypt with RSA public key");
            throw;
        }
    }
    
    public async Task<string> DecryptWithPrivateKeyAsync(string encryptedData, string privateKey)
    {
        try
        {
            var decryptedData = await _rsaService.DecryptAsync(encryptedData, privateKey);
            _logger.LogInformation("Data decrypted with RSA private key");
            return decryptedData;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to decrypt with RSA private key");
            throw;
        }
    }
    
    public async Task<string> SignDataAsync(string data, string privateKey)
    {
        try
        {
            var signature = await _rsaService.SignDataAsync(data, privateKey);
            _logger.LogInformation("Data signed with RSA private key");
            return signature;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to sign data with RSA private key");
            throw;
        }
    }
    
    public async Task<bool> VerifySignatureAsync(string data, string signature, string publicKey)
    {
        try
        {
            var isValid = await _rsaService.VerifySignatureAsync(data, signature, publicKey);
            _logger.LogInformation("Signature verification result: {Result}", isValid ? "Valid" : "Invalid");
            return isValid;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to verify signature");
            throw;
        }
    }
}

public class RsaKeyPair
{
    public string PublicKey { get; set; }
    public string PrivateKey { get; set; }
    public int KeySize { get; set; }
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

Hash Functions

public class HashingService
{
    private readonly IHashService _hashService;
    private readonly ILogger<HashingService> _logger;
    
    public HashingService(IHashService hashService, ILogger<HashingService> logger)
    {
        _hashService = hashService;
        _logger = logger;
    }
    
    public async Task<string> ComputeSha256HashAsync(string input)
    {
        try
        {
            var hash = await _hashService.ComputeHashAsync(input, HashAlgorithmType.SHA256);
            _logger.LogInformation("SHA256 hash computed successfully");
            return hash;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to compute SHA256 hash");
            throw;
        }
    }
    
    public async Task<string> ComputeSha512HashAsync(string input)
    {
        try
        {
            var hash = await _hashService.ComputeHashAsync(input, HashAlgorithmType.SHA512);
            _logger.LogInformation("SHA512 hash computed successfully");
            return hash;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to compute SHA512 hash");
            throw;
        }
    }
    
    public async Task<string> ComputeFileHashAsync(string filePath, HashAlgorithmType algorithm = HashAlgorithmType.SHA256)
    {
        try
        {
            using var fileStream = File.OpenRead(filePath);
            var hash = await _hashService.ComputeHashAsync(fileStream, algorithm);
            _logger.LogInformation("File hash computed for: {FilePath}", filePath);
            return hash;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to compute file hash for: {FilePath}", filePath);
            throw;
        }
    }
    
    public async Task<bool> VerifyFileIntegrityAsync(string filePath, string expectedHash, HashAlgorithmType algorithm = HashAlgorithmType.SHA256)
    {
        try
        {
            var actualHash = await ComputeFileHashAsync(filePath, algorithm);
            var isValid = string.Equals(actualHash, expectedHash, StringComparison.OrdinalIgnoreCase);
            
            _logger.LogInformation("File integrity verification for {FilePath}: {Result}", 
                filePath, isValid ? "Valid" : "Invalid");
            
            return isValid;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to verify file integrity for: {FilePath}", filePath);
            throw;
        }
    }
    
    public async Task<string> ComputeHMACAsync(string message, string key, HashAlgorithmType algorithm = HashAlgorithmType.SHA256)
    {
        try
        {
            var hmac = await _hashService.ComputeHMACAsync(message, key, algorithm);
            _logger.LogInformation("HMAC computed successfully");
            return hmac;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to compute HMAC");
            throw;
        }
    }
}

public enum HashAlgorithmType
{
    MD5,
    SHA1,
    SHA256,
    SHA384,
    SHA512
}

Key Management

public class KeyManagementService
{
    private readonly IKeyManager _keyManager;
    private readonly ILogger<KeyManagementService> _logger;
    
    public KeyManagementService(IKeyManager keyManager, ILogger<KeyManagementService> logger)
    {
        _keyManager = keyManager;
        _logger = logger;
    }
    
    public async Task<string> GenerateEncryptionKeyAsync(int keySize = 32)
    {
        try
        {
            var key = await _keyManager.GenerateKeyAsync(keySize);
            _logger.LogInformation("Encryption key generated with size: {KeySize} bytes", keySize);
            return key;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to generate encryption key");
            throw;
        }
    }
    
    public async Task<string> DeriveKeyFromPasswordAsync(string password, string salt, int iterations = 10000, int keySize = 32)
    {
        try
        {
            var derivedKey = await _keyManager.DeriveKeyFromPasswordAsync(password, salt, iterations, keySize);
            _logger.LogInformation("Key derived from password with {Iterations} iterations", iterations);
            return derivedKey;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to derive key from password");
            throw;
        }
    }
    
    public async Task<string> GenerateSaltAsync(int saltSize = 16)
    {
        try
        {
            var salt = await _keyManager.GenerateSaltAsync(saltSize);
            _logger.LogInformation("Salt generated with size: {SaltSize} bytes", saltSize);
            return salt;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to generate salt");
            throw;
        }
    }
    
    public async Task<KeyRotationResult> RotateKeyAsync(string currentKey, List<string> encryptedData)
    {
        try
        {
            var newKey = await GenerateEncryptionKeyAsync();
            var reencryptedData = new List<string>();
            
            foreach (var data in encryptedData)
            {
                // Decrypt with old key
                var decrypted = await _keyManager.DecryptAsync(data, currentKey);
                
                // Encrypt with new key
                var reencrypted = await _keyManager.EncryptAsync(decrypted, newKey);
                reencryptedData.Add(reencrypted);
            }
            
            var result = new KeyRotationResult
            {
                NewKey = newKey,
                ReencryptedData = reencryptedData,
                RotatedAt = DateTime.UtcNow,
                ItemsRotated = encryptedData.Count
            };
            
            _logger.LogInformation("Key rotation completed. {Count} items re-encrypted", encryptedData.Count);
            return result;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to rotate encryption key");
            throw;
        }
    }
}

public class KeyRotationResult
{
    public string NewKey { get; set; }
    public List<string> ReencryptedData { get; set; }
    public DateTime RotatedAt { get; set; }
    public int ItemsRotated { get; set; }
}

Secure Configuration Storage

public class SecureConfigurationService
{
    private readonly IEncryptionService _encryptionService;
    private readonly IConfiguration _configuration;
    private readonly ILogger<SecureConfigurationService> _logger;
    
    public SecureConfigurationService(
        IEncryptionService encryptionService,
        IConfiguration configuration,
        ILogger<SecureConfigurationService> logger)
    {
        _encryptionService = encryptionService;
        _configuration = configuration;
        _logger = logger;
    }
    
    public async Task<string> GetSecureConfigValueAsync(string key)
    {
        try
        {
            var encryptedValue = _configuration[key];
            if (string.IsNullOrEmpty(encryptedValue))
            {
                return null;
            }
            
            var decryptedValue = await _encryptionService.DecryptStringAsync(encryptedValue);
            _logger.LogInformation("Secure configuration value retrieved for key: {Key}", key);
            return decryptedValue;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to retrieve secure configuration for key: {Key}", key);
            throw;
        }
    }
    
    public async Task SetSecureConfigValueAsync(string key, string value)
    {
        try
        {
            var encryptedValue = await _encryptionService.EncryptStringAsync(value);
            
            // In a real implementation, you would save this to your configuration store
            // This is just for demonstration
            _logger.LogInformation("Secure configuration value encrypted for key: {Key}", key);
            
            // Example: Save to a secure configuration store
            // await _configurationStore.SetValueAsync(key, encryptedValue);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to set secure configuration for key: {Key}", key);
            throw;
        }
    }
    
    public async Task<DatabaseConnectionSecure> GetSecureDatabaseConnectionAsync(string connectionName)
    {
        try
        {
            var encryptedConnectionString = _configuration.GetConnectionString(connectionName);
            var decryptedConnectionString = await _encryptionService.DecryptStringAsync(encryptedConnectionString);
            
            return new DatabaseConnectionSecure
            {
                ConnectionString = decryptedConnectionString,
                Name = connectionName,
                DecryptedAt = DateTime.UtcNow
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to decrypt database connection: {ConnectionName}", connectionName);
            throw;
        }
    }
}

public class DatabaseConnectionSecure
{
    public string Name { get; set; }
    public string ConnectionString { get; set; }
    public DateTime DecryptedAt { get; set; }
}

🔧 Configuration Options

public class EncryptionSettings
{
    public string DefaultEncryptionKey { get; set; }
    public int KeyDerivationIterations { get; set; } = 10000;
    public bool EnableKeyRotation { get; set; } = false;
    public string HashAlgorithm { get; set; } = "SHA256";
    public string EncryptionAlgorithm { get; set; } = "AES256";
    public int DefaultKeySize { get; set; } = 32;
    public int DefaultSaltSize { get; set; } = 16;
    public int RsaKeySize { get; set; } = 2048;
}

// Service registration
services.Configure<EncryptionSettings>(configuration.GetSection("EncryptionSettings"));
services.AddSingleton<IEncryptionService, EncryptionService>();
services.AddSingleton<IPasswordHasher, PasswordHasher>();
services.AddSingleton<IRsaEncryptionService, RsaEncryptionService>();
services.AddSingleton<IHashService, HashService>();
services.AddSingleton<IKeyManager, KeyManager>();

🛡️ Security Best Practices

Key Storage

  • Never store encryption keys in plain text
  • Use secure key management systems (Azure Key Vault, AWS KMS)
  • Implement key rotation policies
  • Use different keys for different data types

Password Security

  • Always use salt for password hashing
  • Use slow hashing algorithms (bcrypt, PBKDF2, Argon2)
  • Implement password strength requirements
  • Never store passwords in plain text

Data Protection

  • Encrypt sensitive data at rest and in transit
  • Use authenticated encryption (AES-GCM)
  • Validate data integrity with HMAC
  • Implement secure key exchange protocols

🏗️ Architecture

The encryption system provides:

  • Security: Industry-standard encryption algorithms and practices
  • Performance: Optimized for high-throughput scenarios
  • Flexibility: Support for multiple encryption methods and key management
  • Compliance: Meets security standards and regulations
  • Scalability: Designed for enterprise-level applications

👨‍💻 Author

Frebin Francis
Fingent Technology Solutions Pvt Ltd

📄 License

Copyright © 2025 Fingent Technology Solutions Pvt Ltd

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 269 9/24/2025