Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Wednesday, May 28, 2025

How to Securing Passwords Against Quantum Computers

Why special care for passwords?

Passwords are stored as hashes, not encrypted, to prevent attackers from recovering the original password if the database leaks. However, with quantum computers, classical password hashing algorithms could become easier to brute force.

Quantum Threats to Password Hashing

  • Grover’s algorithm speeds up brute-force attacks quadratically on symmetric cryptography and hash functions.
  • This means attackers could try roughly the square root of password guesses in the same time compared to classical brute force.
  • Password hashing needs to be computationally expensive and memory-hard, making each guess costly on quantum hardware.

Best Practices for Quantum-Resistant Password Hashing

  1. Use slow, memory-hard hashing algorithms designed for password storage like Argon2, scrypt, or bcrypt.
  2. Always use a unique random salt per password.
  3. Use sufficiently large parameters (iterations, memory, CPU cost) to slow brute forcing.
  4. Use constant-time verification to avoid timing attacks.

C# Examples for Quantum-Resistant Password Hashing:


1. Argon2 — Recommended for quantum resistance

// Install NuGet Package: Install-Package Isopoh.Cryptography.Argon2
using Isopoh.Cryptography.Argon2;
using System;

class Program
{
    static void Main()
    {
        string password = "MyQuantumSafePassword123!";

        // Hash the password with Argon2id
        string hash = Argon2.Hash(password);

        Console.WriteLine($"Argon2 Hash: {hash}");

        // Verify the password
        bool valid = Argon2.Verify(hash, password);
        Console.WriteLine($"Password valid? {valid}");
    }
}

2. bcrypt — Widely used, moderately quantum-resistant

// Install NuGet Package: Install-Package BCrypt.Net-Next
using BCrypt.Net;

class Program
{
    static void Main()
    {
        string password = "MyQuantumSafePassword123!";

        // Generate bcrypt hash
        string hash = BCrypt.Net.BCrypt.HashPassword(password);

        Console.WriteLine($"bcrypt Hash: {hash}");

        // Verify the password
        bool valid = BCrypt.Net.BCrypt.Verify(password, hash);
        Console.WriteLine($"Password valid? {valid}");
    }
}

3. scrypt — Memory-hard, good for resisting quantum attacks

// Install NuGet Package: Install-Package CryptSharpOfficial
using CryptSharp;

class Program
{
    static void Main()
    {
        string password = "MyQuantumSafePassword123!";

        // Generate scrypt hash
        string hash = Crypter.Scrypt.Crypt(password);

        Console.WriteLine($"scrypt Hash: {hash}");

        // Verify the password
        bool valid = Crypter.CheckPassword(password, hash);
        Console.WriteLine($"Password valid? {valid}");
    }
}

4. PBKDF2 — Built-in, less memory-hard, but still usable with high iteration count

using System;
using System.Security.Cryptography;

class Program
{
    static void Main()
    {
        string password = "MyQuantumSafePassword123!";

        // Generate a 16-byte salt
        byte[] salt = new byte[16];
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(salt);
        }

        // Derive a 256-bit key using PBKDF2 with 100,000 iterations and SHA256
        var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100_000, HashAlgorithmName.SHA256);
        byte[] hash = pbkdf2.GetBytes(32);

        // Convert to base64 for storage
        string saltBase64 = Convert.ToBase64String(salt);
        string hashBase64 = Convert.ToBase64String(hash);

        Console.WriteLine($"Salt: {saltBase64}");
        Console.WriteLine($"Hash: {hashBase64}");

        // Verification
        var pbkdf2Verify = new Rfc2898DeriveBytes(password, salt, 100_000, HashAlgorithmName.SHA256);
        byte[] hashToVerify = pbkdf2Verify.GetBytes(32);

        bool valid = CryptographicOperations.FixedTimeEquals(hash, hashToVerify);
        Console.WriteLine($"Password valid? {valid}");
    }
}

Thursday, November 15, 2018

Encrypt database using Transparent Data Encryption (TDE) technology in SQL Server

The Transparent Data Encryption (TDE) encryption technology protects the data in the database by encrypting the underlying files of the database, and not the data itself. So not just the sensitive data but all data in the database will be encrypted. This prevents the data from being hacked.

Assume you are having a database SampleDatabase with credit card details. If you open the backup file in Notepad and search for any card number, you should be able to see the actual data in the backup file. Hence anyone having access to the backup file can read the actual data, without restoring it.

To protect the sensitive data from users who do not have appropriate permission, encrypt the data using TDE feature as given below:

Step 1:

Create a Master Key or Encryption Key in the master database.
Use master;

Create Master Key Encryption By Password = 'C0mplexP@ssw0rd!';

Step 2:

Create a certificate for use as the database encryption key (DEK) protector and is protected by the DMK.
Create Certificate Cert4TDE

With Subject = 'TDE Certificate';


Step 3:

Create a database encryption key (DEK) encrypted with the certificate created in previous step. The supported encryption algorithms are AES with 128-bit, 192-bit, or 256-bit keys or 3 Key Triple DES. The created Master Key and the Certificate will be stored in the master database in an encrypted format.
Use SampleDatabase

Create Database Encryption Key With Algorithm = AES_256 

Encryption By Server Certificate Cert4TDE

Step 4:

Encrypt the data using the Master Key created in previous step.
Alter Database SampleDatabase

Set Encryption ON

Step 5:

We can verify the encryption using the below database query.
SELECT db.name,
    db.is_encrypted,
    ddek.encryption_state,
    ddek.key_algorithm,
    ddek.key_length,
    ddek.percent_complete
FROM sys.databases db
LEFT OUTER JOIN sys.dm_database_encryption_keys ddek
ON db.database_id = ddek.database_id;

GO

From the result we can see the SampleDatabase database is encrypted.

name is_encrypted encryption_state key_algorithm key_length percent_complete
SampleDatabase 1 3 AES 256 0

Step 6:

Repeat Step 3 to backup the database again (with encrypted data) and open the backup file in Notepad. Now search the same card number and see that the data in the backup file is encrypted and secured.

Saturday, June 9, 2018

Add Authorization Header Textbox in Swagger UI for Web API Basic Authentication

I wanted to test the Web API methods using Swagger UI. The Web API has Basic authentication enabled. For each request I need to pass the username and password in the format of base64 encoded. But by default the Swagger UI doesn't have any textbox to accept Authorization credentials parameters. To enable it I had to use the below code in SwaggerConfig.cs file. It should be available inside project's App_Start folder.
internal class AddRequiredHeaderParameter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (operation.parameters == null)
operation.parameters = new List<Parameter>();

operation.parameters.Add(new Parameter
{
name = "Authorization",
@in = "header",
type = "string",
description = "Authorization Header",
required = true
});
}
}
Then add the below code inside the ConfigureSwagger(SwaggerDocsConfig config) method to register it.
private static void ConfigureSwagger(SwaggerDocsConfig config)
{
// existing code
// ...
// ...
config.OperationFilter<AddRequiredHeaderParameter>();
}