密码学Skill cryptography

该技能提供全面的密码学实施指导,涵盖加密算法(如AES-256-GCM)、密码哈希(如Argon2id)、TLS配置、密钥管理和后量子考虑,用于确保数据安全和系统防护。关键词:密码学、加密算法、安全、TLS、密钥管理、后量子密码学。

密码学 0 次安装 2 次浏览 更新于 3/11/2026

名称:密码学 描述:全面的密码学指导,涵盖加密算法、密码哈希、TLS配置、密钥管理和后量子考虑。在实施加密、选择哈希算法、配置TLS/SSL、管理密码学密钥或审查密码学实现时使用。 允许工具:读取、全局搜索、查找、任务

密码学

安全实施密码学操作的全面指导,涵盖加密算法、密码哈希、TLS和密钥管理。

何时使用此技能

在以下情况下使用此技能:

  • 选择加密算法
  • 实施密码哈希
  • 配置TLS/SSL
  • 管理密码学密钥
  • 实施数字签名
  • 生成随机值
  • 审查密码学实现
  • 考虑后量子准备

算法快速参考

加密算法

算法 类型 密钥大小 使用案例 状态
AES-256-GCM 对称 256位 数据加密 ✅ 推荐
ChaCha20-Poly1305 对称 256位 数据加密(移动设备) ✅ 推荐
RSA-OAEP 非对称 2048+位 密钥交换 ✅ 推荐
ECDH (P-256) 非对称 256位 密钥协商 ✅ 推荐
X25519 非对称 256位 密钥协商 ✅ 推荐
DES 对称 56位 ❌ 已弃用
3DES 对称 168位 仅旧版 ⚠️ 避免
Blowfish 对称 32-448位 ⚠️ 避免

签名算法

算法 类型 密钥大小 使用案例 状态
Ed25519 EdDSA 256位 签名 ✅ 推荐
ECDSA (P-256) ECC 256位 签名、JWT ✅ 推荐
RSA-PSS RSA 2048+位 签名 ✅ 推荐
RSA PKCS#1 v1.5 RSA 2048+位 旧版签名 ⚠️ 使用PSS代替

哈希函数

算法 输出大小 使用案例 状态
SHA-256 256位 通用哈希 ✅ 推荐
SHA-384 384位 更高安全性 ✅ 推荐
SHA-512 512位 最高安全性 ✅ 推荐
SHA-3-256 256位 SHA-2替代方案 ✅ 推荐
BLAKE2b 256-512位 快速哈希 ✅ 推荐
MD5 128位 无(已破坏) ❌ 永不使用
SHA-1 160位 无(已破坏) ❌ 永不使用

密码哈希

永远不要使用通用哈希函数(如SHA-256、MD5)来处理密码。

算法比较

算法 推荐程度 内存硬性 备注
Argon2id ✅ 最佳 PHC获胜者,推荐用于新系统
bcrypt ✅ 良好 广泛支持,已验证
scrypt ✅ 良好 良好但调参复杂
PBKDF2 ⚠️ 可接受 NIST批准,但对GPU攻击敏感

Argon2id(推荐)

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

/// <summary>
/// 使用OWASP 2023推荐参数的Argon2id密码哈希器。
/// </summary>
public static class Argon2PasswordHasher
{
    private const int DegreeOfParallelism = 4;
    private const int MemorySize = 65536;  // 64 MB
    private const int Iterations = 3;
    private const int HashLength = 32;
    private const int SaltLength = 16;

    /// <summary>
    /// 使用Argon2id哈希密码。
    /// </summary>
    public static string Hash(string password)
    {
        var salt = RandomNumberGenerator.GetBytes(SaltLength);
        var hash = ComputeHash(password, salt);

        // 返回PHC格式:$argon2id$v=19$m=65536,t=3,p=4$salt$hash
        return $"$argon2id$v=19$m={MemorySize},t={Iterations},p={DegreeOfParallelism}${Convert.ToBase64String(salt)}${Convert.ToBase64String(hash)}";
    }

    /// <summary>
    /// 验证密码与存储的哈希。
    /// </summary>
    public static bool Verify(string storedHash, string password)
    {
        var parts = ParseHash(storedHash);
        if (parts is null) return false;

        var computedHash = ComputeHash(password, parts.Value.Salt);
        return CryptographicOperations.FixedTimeEquals(computedHash, parts.Value.Hash);
    }

    private static byte[] ComputeHash(string password, byte[] salt)
    {
        using var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
        {
            Salt = salt,
            DegreeOfParallelism = DegreeOfParallelism,
            MemorySize = MemorySize,
            Iterations = Iterations
        };
        return argon2.GetBytes(HashLength);
    }

    private static (byte[] Salt, byte[] Hash)? ParseHash(string storedHash)
    {
        // 解析PHC格式:$argon2id$v=19$m=...,t=...,p=...$salt$hash
        var parts = storedHash.Split('$');
        if (parts.Length < 6) return null;

        var salt = Convert.FromBase64String(parts[4]);
        var hash = Convert.FromBase64String(parts[5]);
        return (salt, hash);
    }
}

// 用法
var hash = Argon2PasswordHasher.Hash("user_password");
// 返回:$argon2id$v=19$m=65536,t=3,p=4$...

if (Argon2PasswordHasher.Verify(hash, "user_password"))
{
    // 密码有效
}

bcrypt

using BCrypt.Net;

// 哈希密码(工作因子12 = 2^12次迭代)
var passwordHash = BCrypt.Net.BCrypt.HashPassword("user_password", workFactor: 12);

// 验证密码
if (BCrypt.Net.BCrypt.Verify("user_password", passwordHash))
{
    Console.WriteLine("密码有效");
}

工作因子指南

算法 最小值 推荐值 高安全性
Argon2id t=2, m=19MB t=3, m=64MB t=4, m=128MB
bcrypt 10 12 14
scrypt N=2^14 N=2^16 N=2^18
PBKDF2 310,000 600,000 1,000,000

详细密码哈希指导: 参见密码哈希参考

对称加密

AES-256-GCM(推荐)

using System.Security.Cryptography;

/// <summary>
/// AES-256-GCM加密工具。
/// </summary>
public static class AesGcmEncryption
{
    private const int NonceSize = 12;  // 96位
    private const int TagSize = 16;    // 128位
    private const int KeySize = 32;    // 256位

    /// <summary>
    /// 使用AES-256-GCM加密数据。返回nonce + 密文 + tag。
    /// </summary>
    public static byte[] Encrypt(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> key)
    {
        var nonce = RandomNumberGenerator.GetBytes(NonceSize);
        var ciphertext = new byte[plaintext.Length];
        var tag = new byte[TagSize];

        using var aes = new AesGcm(key, TagSize);
        aes.Encrypt(nonce, plaintext, ciphertext, tag);

        // 组合:nonce + 密文 + tag
        var result = new byte[NonceSize + ciphertext.Length + TagSize];
        nonce.CopyTo(result.AsSpan(0, NonceSize));
        ciphertext.CopyTo(result.AsSpan(NonceSize));
        tag.CopyTo(result.AsSpan(NonceSize + ciphertext.Length));

        return result;
    }

    /// <summary>
    /// 使用AES-256-GCM解密数据。输入是nonce + 密文 + tag。
    /// </summary>
    public static byte[] Decrypt(ReadOnlySpan<byte> combined, ReadOnlySpan<byte> key)
    {
        var nonce = combined[..NonceSize];
        var ciphertext = combined[NonceSize..^TagSize];
        var tag = combined[^TagSize..];

        var plaintext = new byte[ciphertext.Length];

        using var aes = new AesGcm(key, TagSize);
        aes.Decrypt(nonce, ciphertext, tag, plaintext);

        return plaintext;
    }

    /// <summary>
    /// 生成安全的256位密钥。
    /// </summary>
    public static byte[] GenerateKey() => RandomNumberGenerator.GetBytes(KeySize);
}

// 用法
var key = AesGcmEncryption.GenerateKey();
var encrypted = AesGcmEncryption.Encrypt("sensitive data"u8, key);
var decrypted = AesGcmEncryption.Decrypt(encrypted, key);

从密码派生密钥

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

/// <summary>
/// 使用PBKDF2从密码派生加密密钥。
/// </summary>
public static class KeyDerivation
{
    private const int SaltSize = 16;
    private const int KeySize = 32;  // 256位用于AES-256
    private const int Iterations = 600000;  // OWASP 2023推荐

    /// <summary>
    /// 从密码派生加密密钥。返回(密钥,盐)。
    /// </summary>
    public static (byte[] Key, byte[] Salt) DeriveKey(string password, byte[]? salt = null)
    {
        salt ??= RandomNumberGenerator.GetBytes(SaltSize);

        var key = Rfc2898DeriveBytes.Pbkdf2(
            password: Encoding.UTF8.GetBytes(password),
            salt: salt,
            iterations: Iterations,
            hashAlgorithm: HashAlgorithmName.SHA256,
            outputLength: KeySize
        );

        return (key, salt);  // 存储盐与加密数据
    }
}

非对称加密

RSA密钥生成

using System.Security.Cryptography;

/// <summary>
/// 使用OAEP填充的RSA加密。
/// </summary>
public static class RsaEncryption
{
    /// <summary>
    /// 生成RSA密钥对。使用2048最小;4096用于长期安全。
    /// </summary>
    public static RSA GenerateKeyPair(int keySizeInBits = 2048)
    {
        return RSA.Create(keySizeInBits);
    }

    /// <summary>
    /// 使用公钥和OAEP-SHA256加密。
    /// </summary>
    public static byte[] Encrypt(byte[] plaintext, RSA publicKey)
    {
        return publicKey.Encrypt(plaintext, RSAEncryptionPadding.OaepSHA256);
    }

    /// <summary>
    /// 使用私钥和OAEP-SHA256解密。
    /// </summary>
    public static byte[] Decrypt(byte[] ciphertext, RSA privateKey)
    {
        return privateKey.Decrypt(ciphertext, RSAEncryptionPadding.OaepSHA256);
    }
}

// 用法
using var rsa = RsaEncryption.GenerateKeyPair(4096);
var publicKey = rsa.ExportRSAPublicKey();

var ciphertext = RsaEncryption.Encrypt(plaintext, rsa);
var decrypted = RsaEncryption.Decrypt(ciphertext, rsa);

数字签名

using System.Security.Cryptography;

/// <summary>
/// Ed25519数字签名(通过ECDsa与曲线)。
/// 注意:.NET 10有原生Ed25519支持。
/// </summary>
public static class DigitalSignatures
{
    /// <summary>
    /// 创建ECDSA密钥对(P-256,广泛支持)。
    /// </summary>
    public static ECDsa CreateEcdsaKeyPair()
    {
        return ECDsa.Create(ECCurve.NamedCurves.nistP256);
    }

    /// <summary>
    /// 使用ECDSA-SHA256签名消息。
    /// </summary>
    public static byte[] Sign(byte[] message, ECDsa privateKey)
    {
        return privateKey.SignData(message, HashAlgorithmName.SHA256);
    }

    /// <summary>
    /// 验证签名。
    /// </summary>
    public static bool Verify(byte[] message, byte[] signature, ECDsa publicKey)
    {
        return publicKey.VerifyData(message, signature, HashAlgorithmName.SHA256);
    }
}

// 用法
using var ecdsa = DigitalSignatures.CreateEcdsaKeyPair();

var signature = DigitalSignatures.Sign(message, ecdsa);

if (DigitalSignatures.Verify(message, signature, ecdsa))
{
    Console.WriteLine("签名有效");
}
else
{
    Console.WriteLine("签名无效");
}

详细算法选择指导: 参见算法选择指南

TLS配置

推荐TLS设置

# Nginx TLS配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;

# HSTS(HTTP严格传输安全)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# OCSP装订
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;

TLS版本要求

版本 状态 备注
TLS 1.3 ✅ 必需 最佳安全,改进性能
TLS 1.2 ✅ 可接受 使用适当密码套件仍安全
TLS 1.1 ❌ 已弃用 2020年后已禁用
TLS 1.0 ❌ 已弃用 主要漏洞
SSL 3.0 ❌ 已破坏 POODLE攻击
SSL 2.0 ❌ 已破坏 许多漏洞

详细TLS配置: 参见TLS配置指南

密钥管理

密钥层次结构

┌─────────────────────────────────────┐
│  主密钥(KEK)                      │  <- 存储在HSM或KMS中
│  - 加密所有其他密钥                 │
└──────────────────┬──────────────────┘
                   │
       ┌───────────┴───────────┐
       ▼                       ▼
┌──────────────┐      ┌──────────────┐
│  数据密钥1   │      │  数据密钥2   │  <- 用KEK加密
│  (DEK)     │      │  (DEK)     │
└──────────────┘      └──────────────┘

密钥轮换策略

/// <summary>
/// 支持自动轮换的密钥管理器。
/// </summary>
public sealed class KeyManager(IKmsClient kmsClient) : IDisposable
{
    private static readonly TimeSpan RotationPeriod = TimeSpan.FromDays(90);

    private string? _currentKeyId;
    private DateTime? _keyExpiry;
    private readonly SemaphoreSlim _lock = new(1, 1);

    /// <summary>
    /// 获取当前加密密钥,必要时轮换。
    /// </summary>
    public async Task<string> GetCurrentKeyAsync(CancellationToken cancellationToken = default)
    {
        await _lock.WaitAsync(cancellationToken);
        try
        {
            if (NeedsRotation())
            {
                await RotateKeyAsync(cancellationToken);
            }
            return _currentKeyId!;
        }
        finally
        {
            _lock.Release();
        }
    }

    private bool NeedsRotation() =>
        _keyExpiry is null || DateTime.UtcNow > _keyExpiry;

    private async Task RotateKeyAsync(CancellationToken cancellationToken)
    {
        // 在KMS中创建新密钥
        var newKey = await kmsClient.CreateKeyAsync(
            description: $"数据密钥创建于 {DateTime.UtcNow:O}",
            keyUsage: KeyUsage.EncryptDecrypt,
            cancellationToken: cancellationToken
        );

        _currentKeyId = newKey.KeyId;
        _keyExpiry = DateTime.UtcNow.Add(RotationPeriod);

        // 保留旧密钥用于解密(不要立即删除)
        // 用旧密钥加密的数据仍可解密
    }

    public void Dispose() => _lock.Dispose();
}

// KMS客户端接口(实现为Azure密钥保管库、AWS KMS等)
public interface IKmsClient
{
    Task<KmsKey> CreateKeyAsync(string description, KeyUsage keyUsage, CancellationToken cancellationToken);
}

public enum KeyUsage { EncryptDecrypt, SignVerify }
public sealed record KmsKey(string KeyId, DateTime CreatedAt);

随机数生成

using System.Security.Cryptography;

// 用于密码学用途 - 总是使用这些
var secureRandomBytes = RandomNumberGenerator.GetBytes(32);  // 32个随机字节
var secureRandomHex = Convert.ToHexString(RandomNumberGenerator.GetBytes(32));  // 64个十六进制字符
var secureRandomUrl = Convert.ToBase64String(RandomNumberGenerator.GetBytes(32))
    .Replace('+', '-').Replace('/', '_').TrimEnd('=');  // URL安全的base64

// 用于范围内的随机整数(例如,令牌、OTP)
var randomInt = RandomNumberGenerator.GetInt32(100000, 999999);  // 6位数OTP

// 永远不要用于密码学
var random = new Random();
random.Next();  // 不是密码学安全的 - 仅用于游戏/模拟

后量子考虑

当前的非对称算法(如RSA、ECDSA、ECDH)对量子计算机脆弱。

NIST后量子标准(2024)

算法 类型 状态
ML-KEM(Kyber) 密钥封装 ✅ 标准化
ML-DSA(Dilithium) 数字签名 ✅ 标准化
SLH-DSA(SPHINCS+) 数字签名 ✅ 标准化

混合方法(当前推荐)

// 结合经典和后量子算法
// 如果任一被破坏,另一仍提供安全

// 密钥交换:X25519 + ML-KEM-768
// 签名:ECDSA P-256 + ML-DSA-65

// .NET 10+将包括ML-KEM和ML-DSA支持
// 在此之前,使用BouncyCastle等库处理PQ算法

// 这提供了在过渡期间的深度防御:
// 1. 经典算法处理当前威胁
// 2. PQ算法保护免受未来量子攻击
// 3. 组合密钥材料确保任一被破坏时的安全

快速决策树

需要什么密码学操作?

  1. 加密静态数据 → AES-256-GCM
  2. 加密传输中数据 → TLS 1.3
  3. 哈希密码 → Argon2id
  4. 哈希数据(非密码) → SHA-256或BLAKE2b
  5. 数字签名 → Ed25519或ECDSA P-256
  6. 密钥交换 → X25519或ECDH P-256
  7. 消息认证 → HMAC-SHA256
  8. 生成随机值RandomNumberGenerator.GetBytes()RandomNumberGenerator.GetInt32()

安全检查表

加密

  • [ ] 使用认证加密(AES-GCM、ChaCha20-Poly1305)
  • [ ] 用足够熵生成密钥(256位)
  • [ ] 绝不重用nonce/IV
  • [ ] 实施适当的密钥管理

密码哈希

  • [ ] 使用Argon2id、bcrypt或scrypt
  • [ ] 永不使用MD5、SHA-1或无盐哈希
  • [ ] 使用适当的工作因子
  • [ ] 当参数更改时实施重新哈希

TLS

  • [ ] 至少TLS 1.2,推荐TLS 1.3
  • [ ] 仅使用强密码套件
  • [ ] 来自可信CA的有效证书
  • [ ] 启用HSTS

密钥

  • [ ] 安全密钥生成
  • [ ] 适当的密钥存储(敏感密钥用HSM/KMS)
  • [ ] 密钥轮换策略
  • [ ] 安全密钥销毁

参考资料

相关技能

技能 关系
authentication-patterns 使用密码学进行JWT、会话
secrets-management 密码学密钥的安全存储
secure-coding 通用安全实现模式

版本历史

  • v1.0.0 (2025-12-26):初始发布,包括算法、密码哈希、TLS、密钥管理

最后更新: 2025-12-26