Best way to store encryption keys in .NET C
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Storing encryption keys securely is one of the most critical aspects of building a secure .NET application. The encryption algorithm itself may be strong, but if the keys are stored in plaintext in source code or configuration files, the entire system is compromised. This article covers the best approaches for key storage in .NET C#, from cloud-based solutions to OS-level APIs, with working code examples for each.
Why Key Storage Matters
Encryption keys are the single point of failure in any cryptographic system. A leaked key means all data encrypted with that key is exposed. Hardcoding keys in source code is especially dangerous because they end up in version control history, build artifacts, and deployment logs. Even removing a key from the current code does not erase it from Git history.
The goal is to keep keys out of source code entirely and store them in a system that provides access control, audit logging, and automatic rotation.
Option 1: Azure Key Vault (Recommended for Azure Deployments)
Azure Key Vault is a cloud-hosted HSM-backed service that stores keys, secrets, and certificates. It integrates natively with .NET through the Azure.Security.KeyVault.Secrets package.
Install the required packages:
Retrieve a secret at runtime:
DefaultAzureCredential automatically picks up credentials from environment variables, managed identity, Visual Studio, or the Azure CLI, so no credentials need to be hardcoded. In production, use a managed identity assigned to your App Service or VM so the application authenticates to Key Vault without any secrets at all.
Option 2: AWS Secrets Manager (For AWS Deployments)
If you are on AWS, Secrets Manager provides similar functionality:
AWS Secrets Manager supports automatic key rotation, versioning, and fine-grained IAM access policies.
Option 3: Windows DPAPI (For Windows-Only Applications)
The Data Protection API (DPAPI) is built into Windows and encrypts data using credentials tied to the current user or machine. This is suitable for desktop applications or Windows services that do not run in the cloud.
DataProtectionScope.CurrentUser means only the same Windows user can decrypt the data. DataProtectionScope.LocalMachine allows any user on the same machine to decrypt it, which is less secure but necessary for some service scenarios.
Option 4: ASP.NET Core Data Protection API
ASP.NET Core includes its own Data Protection system designed for protecting sensitive data like authentication tokens. You can also use it for custom key storage:
Register it in Program.cs:
Option 5: Environment Variables (Minimum Viable Approach)
For simple deployments where a cloud KMS is not available, environment variables keep keys out of source code. This is the minimum acceptable approach:
In ASP.NET Core, use the configuration system with user secrets during development:
User secrets are stored outside the project directory in %APPDATA%\Microsoft\UserSecrets\ on Windows, so they never end up in version control.
Key Rotation Strategy
Regardless of which storage method you choose, implement key rotation. Old keys should remain available to decrypt existing data, while new data is encrypted with the current key:
Common Pitfalls
Hardcoding keys in appsettings.json. This file is committed to source control by default. Even if you add it to .gitignore later, the key may already be in the Git history. Use user secrets for development and environment variables or a KMS for production.
Logging keys accidentally. Structured logging frameworks can capture entire configuration objects. Make sure your key values are never included in log output. Mark key properties with [JsonIgnore] or use a custom serializer that redacts sensitive fields.
Using the same key for all environments. Development, staging, and production should each have separate encryption keys. If a development key is compromised, production data should not be affected.
Not setting proper file permissions on key files. If you store encrypted keys on disk (DPAPI approach), ensure the file permissions restrict access to only the application's service account.
Summary
For cloud deployments, use Azure Key Vault or AWS Secrets Manager. These provide HSM-backed storage, access control, audit logging, and automatic rotation. For Windows desktop applications, DPAPI provides machine-level or user-level encryption without external dependencies. As a minimum baseline, use environment variables and ASP.NET Core user secrets to keep keys out of source code. Never hardcode keys in source files, configuration files committed to version control, or log output.

