C# 常用密码加密与解密技术完全指南

发布于:2025-05-22 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

  1. 密码安全的核心概念

    • 加密 vs 哈希:何时使用?

    • 密钥管理的重要性

    • 常见攻击手段(中间人攻击、彩虹表)

  2. 基础加密技术

    • 对称加密(AES)

    • 非对称加密(RSA)

    • 哈希算法(SHA3、HMAC)

  3. 现代安全实践

    • 密码存储方案(PBKDF2、BCrypt)

    • 数据保护API(Microsoft DPAPI)

    • 安全随机数生成(CSPRNG)

  4. 代码实战

    • AES加密解密完整流程

    • RSA密钥对生成与加密

    • 使用BCrypt安全存储密码

  5. 安全陷阱与防御

    • 不要使用ECB模式!

    • 密钥硬编码的风险

    • 防止Padding Oracle攻击

  6. 企业级解决方案

    • Azure Key Vault集成

    • 硬件安全模块(HSM)

  7. 常见问题解答


1. 密码安全的核心概念

加密 vs 哈希

特性 加密 哈希
可逆性
适用场景 数据传输(如信用卡号) 密码存储
典型算法 AES、RSA SHA3、PBKDF2、BCrypt

密钥管理三原则

  1. 保密性:主密钥必须安全存储(如HSM)

  2. 轮换策略:定期更换加密密钥

  3. 最小权限:按需分配密钥访问权限


2. 基础加密技术

AES对称加密(CBC模式示例)

using System.Security.Cryptography;

public class AesHelper
{
    public static (string cipherText, string iv) Encrypt(string plainText, byte[] key)
    {
        using Aes aes = Aes.Create();
        aes.Key = key;
        aes.Mode = CipherMode.CBC; // 必须使用CBC或GCM模式
        aes.Padding = PaddingMode.PKCS7;

        // 生成随机IV(16字节)
        aes.GenerateIV();
        byte[] iv = aes.IV;

        ICryptoTransform encryptor = aes.CreateEncryptor();
        byte[] encrypted;
        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
            {
                byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
                cs.Write(plainBytes, 0, plainBytes.Length);
            }
            encrypted = ms.ToArray();
        }
        return (Convert.ToBase64String(encrypted), Convert.ToBase64String(iv));
    }

    public static string Decrypt(string cipherText, byte[] key, string ivBase64)
    {
        using Aes aes = Aes.Create();
        aes.Key = key;
        aes.IV = Convert.FromBase64String(ivBase64);
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        ICryptoTransform decryptor = aes.CreateDecryptor();
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (var ms = new MemoryStream(cipherBytes))
        using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
        using (var sr = new StreamReader(cs))
        {
            return sr.ReadToEnd();
        }
    }
}

RSA非对称加密

using System.Security.Cryptography;

public class RsaHelper
{
    // 生成2048位密钥对
    public static (string publicKey, string privateKey) GenerateKeyPair()
    {
        using RSA rsa = RSA.Create(2048);
        return (
            Convert.ToBase64String(rsa.ExportRSAPublicKey()),
            Convert.ToBase64String(rsa.ExportRSAPrivateKey())
        );
    }

    public static string Encrypt(string plainText, string publicKeyBase64)
    {
        byte[] publicKey = Convert.FromBase64String(publicKeyBase64);
        using RSA rsa = RSA.Create();
        rsa.ImportRSAPublicKey(publicKey, out _);
        byte[] encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(plainText), RSAEncryptionPadding.OaepSHA256);
        return Convert.ToBase64String(encrypted);
    }

    public static string Decrypt(string cipherText, string privateKeyBase64)
    {
        byte[] privateKey = Convert.FromBase64String(privateKeyBase64);
        using RSA rsa = RSA.Create();
        rsa.ImportRSAPrivateKey(privateKey, out _);
        byte[] decrypted = rsa.Decrypt(Convert.FromBase64String(cipherText), RSAEncryptionPadding.OaepSHA256);
        return Encoding.UTF8.GetString(decrypted);
    }
}

3. 现代安全实践

密码存储方案(PBKDF2 + Salt)

using System.Security.Cryptography;

public class PasswordHasher
{
    // 生成密码哈希(推荐参数)
    public static (string hash, string salt) HashPassword(string password)
    {
        byte[] salt = new byte[32];
        using var rng = RandomNumberGenerator.Create();
        rng.GetBytes(salt);
        int iterations = 150000; // OWASP 2021推荐值

        using var pbkdf2 = new Rfc2898DeriveBytes(
            password,
            salt,
            iterations,
            HashAlgorithmName.SHA512
        );
        byte[] hash = pbkdf2.GetBytes(64); // 64字节=512位
        return (
            Convert.ToBase64String(hash),
            Convert.ToBase64String(salt)
        );
    }

    // 验证密码
    public static bool VerifyPassword(string password, string storedHash, string storedSalt)
    {
        byte[] salt = Convert.FromBase64String(storedSalt);
        byte[] hash = Convert.FromBase64String(storedHash);
        using var pbkdf2 = new Rfc2898DeriveBytes(
            password,
            salt,
            150000,
            HashAlgorithmName.SHA512
        );
        byte[] testHash = pbkdf2.GetBytes(64);
        return CryptographicOperations.FixedTimeEquals(hash, testHash);
    }
}

Microsoft数据保护API(DPAPI)

// 适合本地数据保护(自动管理密钥)
using Microsoft.AspNetCore.DataProtection;

public class DataProtector
{
    private readonly IDataProtector _protector;

    public DataProtector(IDataProtectionProvider provider)
    {
        _protector = provider.CreateProtector("AppName.Purpose");
    }

    public string Protect(string input) => _protector.Protect(input);
    public string Unprotect(string protectedData) => _protector.Unprotect(protectedData);
}

4. 安全陷阱与防御

AES加密的致命错误

// 错误示例:使用ECB模式(不安全的!)
aes.Mode = CipherMode.ECB; // ❌ 相同输入产生相同输出,易被分析

// 正确做法:使用CBC或GCM模式
aes.Mode = CipherMode.CBC; // ✅ 需要随机IV
aes.GenerateIV();          // 每次加密生成新IV

密钥存储的典型错误

// 错误:硬编码密钥
byte[] key = Encoding.ASCII.GetBytes("ThisIsASecretKey123"); // ❌

// 正确:从安全存储获取
byte[] key = Convert.FromBase64String(
    ConfigurationManager.AppSettings["EncryptionKey"] // ✅ 使用密钥库
);

5. 企业级解决方案

Azure Key Vault集成

using Azure.Security.KeyVault.Keys.Cryptography;

public async Task<string> EncryptWithAzureKeyVault(string text)
{
    var credential = new DefaultAzureCredential();
    var cryptoClient = new CryptographyClient(
        new Uri("https://your-vault.vault.azure.net/keys/key-name/"),
        credential
    );
    byte[] data = Encoding.UTF8.GetBytes(text);
    EncryptResult result = await cryptoClient.EncryptAsync(EncryptionAlgorithm.RsaOaep, data);
    return Convert.ToBase64String(result.Ciphertext);
}

6. 常见问题解答

Q1:应该选择对称还是非对称加密?

  • 对称加密(AES):速度快,适合大数据量(如文件加密)

  • 非对称加密(RSA):适合密钥交换或小数据加密

Q2:如何安全存储加密密钥?

  • 开发环境:使用dotnet user-secrets

  • 生产环境:Azure Key Vault/AWS KMS/HSM

Q3:加密后的数据如何比较?

  • 使用固定时间比较函数防止时序攻击:

    // 正确方式
    CryptographicOperations.FixedTimeEquals(hash1, hash2);
    
    // 错误方式
    if (hash1 == hash2) { ... } // ❌ 可能泄露比较时间

Q4:如何迁移旧加密系统?

  1. 解密旧数据(使用旧密钥)

  2. 用新算法/密钥重新加密

  3. 销毁旧密钥(物理安全)


网站公告

今日签到

点亮在社区的每一天
去签到