ASP.NET Core  

Encrypting Sensitive Data in ASP.NET Core Applications

Protecting sensitive data (such as connection strings, API keys, personal information, or financial details) is critical in modern web applications. ASP.NET Core provides robust security APIs and integration with .NET cryptography libraries to help developers safeguard data at rest and in transit. This article explores best practices and implementation strategies for encrypting sensitive data in ASP.NET Core applications.

Why Encrypt Sensitive Data?

Sensitive information is often stored in databases or configuration files or transmitted across APIs. If left unprotected, attackers can exploit vulnerabilities to steal or tamper with this data. Encryption ensures that even if unauthorized access occurs, the information remains unreadable without the appropriate keys.

Common Scenarios

  • Database fields: Encrypting credit card numbers, national IDs, or personal records.

  • Configuration secrets: Protecting API keys, client secrets, and database credentials.

  • File storage: Encrypting uploaded documents or backups.

  • Cache/session data: Securing tokens or user-specific session values.

Built-in Cryptography in .NET

ASP.NET Core uses the System.Security.Cryptography namespace, which provides:

  • Symmetric encryption: Fast, uses the same key for encryption and decryption (e.g., AES).

  • Asymmetric encryption: Uses a public/private key pair (e.g., RSA).

  • Hashing and HMAC: For one-way integrity verification (e.g., SHA256, HMACSHA256).

  • Data Protection API (DPAPI): A high-level API for protecting sensitive data like cookies, tokens, and keys.

Using ASP.NET Core Data Protection API

The Data Protection API is the recommended way to handle encryption for most ASP.NET Core scenarios, especially for protecting short-lived secrets.

using Microsoft.AspNetCore.DataProtection;

public class EncryptionService
{
    private readonly IDataProtector _protector;

    public EncryptionService(IDataProtectionProvider provider)
    {
        _protector = provider.CreateProtector("SensitiveData.Encryption");
    }

    public string Encrypt(string plainText)
    {
        return _protector.Protect(plainText);
    }

    public string Decrypt(string cipherText)
    {
        return _protector.Unprotect(cipherText);
    }
}

Usage in Startup/Program.cs:

builder.Services.AddDataProtection();
builder.Services.AddScoped<EncryptionService>();

This method automatically handles key rotation and persistence, making it secure and easy to maintain.

Encrypting Data with AES

For custom scenarios (e.g., encrypting large files or database fields), AES (Advanced Encryption Standard) is the go-to option.

using System.Security.Cryptography;
using System.Text;

public static class AesEncryptionHelper
{
    public static (byte[] cipher, byte[] iv) Encrypt(string plainText, byte[] key)
    {
        using var aes = Aes.Create();
        aes.Key = key;
        aes.GenerateIV();

        using var encryptor = aes.CreateEncryptor();
        var plainBytes = Encoding.UTF8.GetBytes(plainText);
        var cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

        return (cipherBytes, aes.IV);
    }

    public static string Decrypt(byte[] cipherBytes, byte[] key, byte[] iv)
    {
        using var aes = Aes.Create();
        aes.Key = key;
        aes.IV = iv;

        using var decryptor = aes.CreateDecryptor();
        var plainBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);

        return Encoding.UTF8.GetString(plainBytes);
    }
}

Important: Securely store the encryption key (e.g., in Azure Key Vault, AWS KMS, or HashiCorp Vault). Never hardcode keys in your source code.

Protecting Configuration Secrets

ASP.NET Core encourages storing sensitive configuration in:

  • User Secrets (local development)

  • Environment variables

  • Azure Key Vault / AWS Secrets Manager

Example with Azure Key Vault:

builder.Configuration.AddAzureKeyVault(
    new Uri($"https://{keyVaultName}.vault.azure.net/"),
    new DefaultAzureCredential());

This ensures that secrets are never stored in plain text inside appsettings.json.

Database Field Encryption

When storing sensitive values in a database:

  1. Use AES to encrypt fields before insertion.

  2. Store the IV with the record for decryption.

  3. Use hashing (not encryption) for passwords.

Example with Entity Framework Core Value Converters:

modelBuilder.Entity<User>()
    .Property(u => u.Ssn)
    .HasConversion(
        v => Convert.ToBase64String(AesEncryptionHelper.Encrypt(v, key).cipher),
        v => AesEncryptionHelper.Decrypt(Convert.FromBase64String(v), key, iv));

Best Practices

  • Use Data Protection API for app-level secrets and tokens.

  • Prefer AES for strong, fast symmetric encryption.

  • Never hardcode keys—store them in Key Vaults or environment variables.

  • Encrypt at rest and in transit (TLS for data in transit).

  • Enable key rotation to minimize risk if a key is compromised.

  • Hash passwords instead of encrypting them (PasswordHasher<TUser> in ASP.NET Core Identity).

Conclusion

Encrypting sensitive data in ASP.NET Core applications is essential for protecting user trust and complying with security regulations like GDPR, HIPAA, and PCI DSS. By leveraging the Data Protection API for application-level needs and AES encryption for database or file storage, you can secure your applications against data theft and misuse.