Skip to main content
Login Register
Code2night
  • Home
  • Blog Archive
  • Learn
    • Tutorials
    • Videos
  • Interview Q&A
  • Products
  • Resources
    • Cheatsheets
    • Tech Comparisons
  • Languages
    • Angular Angular js ASP.NET Asp.net Core ASP.NET Core, C# ASP.NET MVC ASP.NET Web Forms C C# C#, ASP.NET Core, Dapper
      C#, ASP.NET Core, Dapper, Entity Framework DotNet General Web Development HTML, CSS HTML/CSS Java JavaScript JavaScript, HTML, CSS JavaScript, Node.js Node.js
      Python Python 3.11, Pandas, SQL Python 3.11, SQL Python 3.11, SQLAlchemy Python 3.11, SQLAlchemy, SQL Python 3.11, SQLite React Security SQL Server TypeScript
  • Post Blog
  • Tools
    • Beautifiers
      JSON Beautifier HTML Beautifier XML Beautifier CSS Beautifier JS Beautifier SQL Formatter
      Dev Utilities
      JWT Decoder Regex Tester Diff Checker Cron Explainer String Escape Hash Generator Password Generator
      Converters
      Base64 Encode/Decode URL Encoder/Decoder JSON to CSV CSV to JSON JSON to TypeScript Markdown to HTML Number Base Converter Timestamp Converter Case Converter
      Generators
      UUID / GUID Generator Lorem Ipsum QR Code Generator Meta Tag Generator
      Image Tools
      Image Converter Image Resizer Image Compressor Image to Base64 PNG to ICO Background Remover Color Picker
      Text & Content
      Word Counter PDF Editor
      SEO & Web
      SEO Analyzer URL Checker World Clock
  1. Home
  2. Blog
  3. ASP.NET Core
  4. CWE-312: Preventing Cleartext Storage of Passwords and Tokens in ASP.NET Core

CWE-312: Preventing Cleartext Storage of Passwords and Tokens in ASP.NET Core

Date- Jun 03,2026 606
cwe 312 asp.net core

Overview

The Common Weakness Enumeration (CWE) identifies vulnerabilities in software, and one of the most significant is CWE-312: Cleartext Storage of Passwords and Tokens. This vulnerability arises when sensitive data, such as passwords and authentication tokens, are stored in an unencrypted format, making them easily accessible to unauthorized users. The consequences of such negligence can be dire, leading to data breaches, identity theft, and loss of user trust.

In the context of ASP.NET Core, which is widely used for building web applications, it is crucial to implement secure practices for storing sensitive information. This article will explore various methods for preventing cleartext storage, the importance of encryption, and best practices for handling passwords and tokens securely. Real-world use cases, such as user authentication and API token management, will be discussed to illustrate these concepts.

Prerequisites

  • ASP.NET Core knowledge: Familiarity with the ASP.NET Core framework and its components is essential.
  • C# programming: A good grasp of C# is necessary to implement the examples provided.
  • Cryptography basics: Understanding basic cryptography concepts will help in grasping encryption techniques.
  • Development environment: A working setup of Visual Studio or Visual Studio Code for testing the code examples.

Importance of Secure Password Storage

Storing passwords securely is a fundamental aspect of application security. When passwords are stored in plaintext, any breach of the database can lead to catastrophic consequences, as attackers can easily retrieve user credentials. This is particularly concerning in today's digital landscape, where data breaches are increasingly common.

To mitigate these risks, developers must utilize hashing algorithms and salting techniques to protect passwords. Hashing transforms the original password into a fixed-size string of characters, which is not reversible, while salting adds a unique value to each password before hashing. This ensures that even if two users have the same password, their stored values will differ, complicating attacks.

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

public class PasswordHasher
{
    public string HashPassword(string password)
    {
        // Generate a salt
        using (var rng = new RNGCryptoServiceProvider())
        {
            byte[] salt = new byte[16];
            rng.GetBytes(salt);
            // Hash the password with the salt
            using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000))
            {
                byte[] hash = pbkdf2.GetBytes(20);
                // Combine salt and hash into a single array
                byte[] hashBytes = new byte[36];
                Array.Copy(salt, 0, hashBytes, 0, 16);
                Array.Copy(hash, 0, hashBytes, 16, 20);
                // Convert to Base64 string
                return Convert.ToBase64String(hashBytes);
            }
        }
    }
}

This code snippet demonstrates a simple password hashing implementation using Rfc2898DeriveBytes, which is a standard way to hash passwords securely.

Line-by-line explanation:

  • using System.Security.Cryptography; - Imports cryptographic services.
  • public class PasswordHasher - Defines a class for password hashing.
  • public string HashPassword(string password) - Method to hash the provided password.
  • using (var rng = new RNGCryptoServiceProvider()) - Initializes a random number generator for creating a salt.
  • byte[] salt = new byte[16]; - Creates a 16-byte array for the salt.
  • rng.GetBytes(salt); - Fills the salt with random bytes.
  • using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000)) - Uses PBKDF2 to hash the password with the salt over 10,000 iterations.
  • byte[] hash = pbkdf2.GetBytes(20); - Retrieves the hash of the password.
  • byte[] hashBytes = new byte[36]; - Creates a new array to store combined salt and hash.
  • Array.Copy(salt, 0, hashBytes, 0, 16); - Copies the salt into the hashBytes array.
  • Array.Copy(hash, 0, hashBytes, 16, 20); - Copies the hash into the hashBytes array.
  • return Convert.ToBase64String(hashBytes); - Converts the combined byte array to a Base64 string for storage.

Salting and Hashing Explained

Salting is a technique that enhances security by adding a random value (the salt) to the password before hashing. This means that even if two users choose the same password, their hashes will differ due to the unique salts. This practice prevents attackers from using precomputed rainbow tables to crack passwords.

Hashing algorithms like PBKDF2, bcrypt, or Argon2 are designed to be slow, making brute-force attacks less feasible. The use of a high iteration count in PBKDF2, for example, increases the time it takes to compute a hash, thereby slowing down potential attackers.

Storing Tokens Securely

Similar to passwords, tokens used in authentication (like JWTs or OAuth tokens) should never be stored in cleartext. Storing tokens securely is essential for protecting user sessions and sensitive data. Tokens should be encrypted before storage, ensuring that even if the storage medium is compromised, the tokens remain protected.

ASP.NET Core provides several options for secure token storage, including using secure cookies, in-memory caching, or encrypted databases. Each method has its own use cases and trade-offs, which will be explored in the following sections.

public class TokenService
{
    private readonly string _encryptionKey;

    public TokenService(string encryptionKey)
    {
        _encryptionKey = encryptionKey;
    }

    public string EncryptToken(string token)
    {
        using (var aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(_encryptionKey);
            aes.GenerateIV();
            var iv = aes.IV;
            using (var encryptor = aes.CreateEncryptor(aes.Key, iv))
            {
                using (var ms = new MemoryStream())
                {
                    ms.Write(iv, 0, iv.Length);
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        using (var sw = new StreamWriter(cs))
                        {
                            sw.Write(token);
                        }
                    }
                    return Convert.ToBase64String(ms.ToArray());
                }
            }
        }
    }
}

This code shows how to encrypt tokens using the AES algorithm.

Line-by-line explanation:

  • public class TokenService - Defines a class for managing token encryption.
  • private readonly string _encryptionKey; - Stores the encryption key securely.
  • public TokenService(string encryptionKey) - Constructor that initializes the encryption key.
  • public string EncryptToken(string token) - Method for encrypting the provided token.
  • using (var aes = Aes.Create()) - Initializes the AES encryption algorithm.
  • aes.Key = Encoding.UTF8.GetBytes(_encryptionKey); - Sets the encryption key.
  • aes.GenerateIV(); - Generates a new initialization vector (IV).
  • var iv = aes.IV; - Stores the generated IV for use in encryption.
  • using (var encryptor = aes.CreateEncryptor(aes.Key, iv)) - Creates an encryptor using the key and IV.
  • using (var ms = new MemoryStream()) - Initializes a memory stream for storing encrypted data.
  • ms.Write(iv, 0, iv.Length); - Writes the IV to the memory stream.
  • using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) - Wraps the memory stream in a crypto stream.
  • using (var sw = new StreamWriter(cs)) - Creates a stream writer for writing the token.
  • sw.Write(token); - Writes the token to the crypto stream.
  • return Convert.ToBase64String(ms.ToArray()); - Converts the encrypted data to a Base64 string for storage.

Token Expiration and Revocation

It is important to implement token expiration and revocation mechanisms to enhance security further. Tokens should have a limited lifespan, after which they become invalid. This can be achieved through expiration timestamps embedded within the token payload.

For sensitive operations, it may also be necessary to revoke tokens explicitly. This can be achieved by maintaining a blacklist of revoked tokens in the application, ensuring that even if a token is valid, it cannot be used if it has been revoked.

Edge Cases & Gotchas

When dealing with password storage and token management, several pitfalls can lead to security vulnerabilities. One common mistake is using weak hashing algorithms like MD5 or SHA1, which are no longer considered secure. Instead, developers should use modern algorithms like PBKDF2, bcrypt, or Argon2.

// Incorrect Approach: Using MD5 for password hashing
public string IncorrectHashPassword(string password)
{
    using (var md5 = MD5.Create())
    {
        byte[] inputBytes = Encoding.UTF8.GetBytes(password);
        byte[] hashBytes = md5.ComputeHash(inputBytes);
        return Convert.ToBase64String(hashBytes);
    }
}

This incorrect approach shows how using MD5 can lead to vulnerabilities.

Line-by-line explanation:

  • using (var md5 = MD5.Create()) - Initializes the MD5 hashing algorithm.
  • byte[] inputBytes = Encoding.UTF8.GetBytes(password); - Converts the password to a byte array.
  • byte[] hashBytes = md5.ComputeHash(inputBytes); - Computes the hash using MD5.
  • return Convert.ToBase64String(hashBytes); - Converts the hash to a Base64 string.

This approach is flawed due to the vulnerabilities associated with MD5. Developers are encouraged to always opt for stronger hashing methods.

Performance & Best Practices

When implementing secure password storage and token management, performance should be considered. Hashing algorithms that are too slow can degrade application performance, particularly under high load. Therefore, it's essential to find a balance between security and performance.

Best practices include:

  • Use a secure hashing algorithm: Always opt for algorithms like PBKDF2, bcrypt, or Argon2.
  • Implement rate limiting: Prevent brute-force attacks by limiting the number of login attempts.
  • Regularly update libraries: Ensure cryptographic libraries are up-to-date to protect against known vulnerabilities.
  • Use HTTPS: Always encrypt data in transit to protect sensitive information.

Real-World Scenario: User Authentication System

Let's implement a simple user authentication system that securely stores passwords and manages tokens. We will create a basic ASP.NET Core web application with user registration and login functionalities.

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

public class User
{
    public string Username { get; set; }
    public string PasswordHash { get; set; }
}

public class AuthController : ControllerBase
{
    private static List _users = new List();
    private readonly PasswordHasher _passwordHasher;

    public AuthController()
    {
        _passwordHasher = new PasswordHasher();
    }

    [HttpPost("/register")]
    public IActionResult Register(string username, string password)
    {
        var passwordHash = _passwordHasher.HashPassword(password);
        _users.Add(new User { Username = username, PasswordHash = passwordHash });
        return Ok("User registered successfully.");
    }

    [HttpPost("/login")]
    public IActionResult Login(string username, string password)
    {
        var user = _users.Find(u => u.Username == username);
        if (user == null || user.PasswordHash != _passwordHasher.HashPassword(password))
        {
            return Unauthorized("Invalid credentials.");
        }
        return Ok("Login successful.");
    }
}

This is a simple user authentication implementation.

Line-by-line explanation:

  • public class User - Defines a user class with properties for username and password hash.
  • private static List _users = new List(); - In-memory list to store registered users.
  • private readonly PasswordHasher _passwordHasher; - Initializes a password hasher instance.
  • public AuthController() - Constructor that initializes the password hasher.
  • [HttpPost("/register")] - Defines a registration endpoint.
  • public IActionResult Register(string username, string password) - Method for registering a new user.
  • var passwordHash = _passwordHasher.HashPassword(password); - Hashes the provided password.
  • _users.Add(new User { Username = username, PasswordHash = passwordHash }); - Adds the new user to the list.
  • return Ok("User registered successfully."); - Returns a success response.
  • [HttpPost("/login")] - Defines a login endpoint.
  • public IActionResult Login(string username, string password) - Method for authenticating a user.
  • var user = _users.Find(u => u.Username == username); - Finds the user in the list.
  • if (user == null || user.PasswordHash != _passwordHasher.HashPassword(password)) - Checks if the user exists and if the password matches.
  • return Unauthorized("Invalid credentials."); - Returns an unauthorized response if credentials are invalid.
  • return Ok("Login successful."); - Returns a success response if login is successful.

Conclusion

  • Always hash passwords: Use secure hashing algorithms with salting.
  • Encrypt tokens: Ensure that tokens are encrypted before storage.
  • Implement expiration and revocation: Use token expiration and revocation mechanisms to enhance security.
  • Avoid common pitfalls: Do not use outdated hashing algorithms like MD5.
  • Follow best practices: Regularly update libraries, use HTTPS, and implement rate limiting.

S
Shubham Saini
Programming author at Code2Night — sharing tutorials on ASP.NET, C#, and more.
View all posts →

Related Articles

CWE-613: Implementing Proper Session Expiry and Token Revocation in ASP.NET Core
Jun 02, 2026
CWE-330: Generating Cryptographically Secure Random Values in ASP.NET Core
Apr 28, 2026
CWE-327: Replacing Weak Cryptography in ASP.NET Core with SHA-256 and AES
Apr 28, 2026
Understanding CWE-327: The Risks of Using Broken Cryptographic Algorithms like MD5 and SHA1
Mar 18, 2026
Previous in ASP.NET Core
CWE-311: Securely Encrypting Sensitive Data at Rest Using ASP.NET…
Next in ASP.NET Core
CWE-20: Mastering Input Validation in ASP.NET Core with Data Anno…
Buy me a pizza

Comments

🔥 Trending This Month

  • 1
    CWE-269: Improper Privilege Management - Implementing the … 361 views
  • 2
    Building Custom Bedrock Add-Ons with JavaScript: A Complet… 1,937 views
  • 3
    Send Email With HTML Template And PDF Using ASP.Net C# 17,201 views
  • 4
    Error-An error occurred while processing your request in .… 11,964 views
  • 5
    Elasticsearch Integration in ASP.NET Core - Full-Text Sear… 243 views
  • 6
    Fix Gemini API Error 429: Quota Exceeded on Free Tier (Sys… 827 views
  • 7
    Integrating Google reCAPTCHA v3 in ASP.NET Core for Seamle… 613 views

On this page

🎯

Interview Prep

Ace your ASP.NET Core interview with curated Q&As for all levels.

View ASP.NET Core Interview Q&As

More in ASP.NET Core

  • How to Encrypt and Decrypt Password in Asp.Net 26683 views
  • Exception Handling Asp.Net Core 21720 views
  • HTTP Error 500.31 Failed to load ASP NET Core runtime 21177 views
  • How to implement Paypal in Asp.Net Core 20127 views
  • Task Scheduler in Asp.Net core 18201 views
View all ASP.NET Core posts →

Tags

AspNet C# programming AspNet MVC c programming AspNet Core C software development tutorial MVC memory management Paypal coding coding best practices data structures programming tutorial tutorials object oriented programming Slick Slider StripeNet
Free Download for Youtube Subscribers!

First click on Subscribe Now and then subscribe the channel and come back here.
Then Click on "Verify and Download" button for download link

Subscribe Now | 1780
Download
Support Us....!

Please Subscribe to support us

Thank you for Downloading....!

Please Subscribe to support us

Continue with Downloading
Be a Member
Join Us On Whatsapp
Code2Night

A community platform for sharing programming knowledge, tutorials, and blogs. Learn, write, and grow with developers worldwide.

Panipat, Haryana, India
info@code2night.com
Quick Links
  • Home
  • Blog Archive
  • Products
  • Tutorials
  • About Us
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Guest Posts
  • SEO Analyzer
Dev Tools
  • JSON Beautifier
  • HTML Beautifier
  • CSS Beautifier
  • JS Beautifier
  • SQL Formatter
  • Diff Checker
  • Regex Tester
  • Markdown to HTML
  • Word Counter
More Tools
  • Password Generator
  • QR Code Generator
  • Hash Generator
  • Base64 Encoder
  • JWT Decoder
  • UUID Generator
  • Image Converter
  • PNG to ICO
  • SEO Analyzer
By Language
  • Angular
  • Angular js
  • ASP.NET
  • Asp.net Core
  • ASP.NET Core, C#
  • ASP.NET MVC
  • ASP.NET Web Forms
  • C
  • C#
  • C#, ASP.NET Core, Dapper
  • C#, ASP.NET Core, Dapper, Entity Framework
  • DotNet
  • General Web Development
  • HTML, CSS
  • HTML/CSS
  • Java
  • JavaScript
  • JavaScript, HTML, CSS
  • JavaScript, Node.js
  • Node.js
  • Python
  • Python 3.11, Pandas, SQL
  • Python 3.11, SQL
  • Python 3.11, SQLAlchemy
  • Python 3.11, SQLAlchemy, SQL
  • Python 3.11, SQLite
  • React
  • Security
  • SQL Server
  • TypeScript
© 2026 Code2Night. All Rights Reserved.
Made with for developers  |  Privacy  ·  Terms
Translate Page
We use cookies to improve your experience and analyze site traffic. By clicking Accept, you consent to our use of cookies. Privacy Policy
Accessibility
Text size
High contrast
Grayscale
Dyslexia font
Highlight links
Pause animations
Large cursor