cryptography

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cryptography

密码学

Comprehensive guidance for implementing cryptographic operations securely, covering encryption algorithms, password hashing, TLS, and key management.
关于安全实现密码学操作的全面指南,涵盖加密算法、密码哈希、TLS以及密钥管理。

When to Use This Skill

何时使用本技能

Use this skill when:
  • Choosing encryption algorithms
  • Implementing password hashing
  • Configuring TLS/SSL
  • Managing cryptographic keys
  • Implementing digital signatures
  • Generating random values
  • Reviewing cryptographic implementations
  • Considering post-quantum readiness
在以下场景使用本技能:
  • 选择加密算法
  • 实现密码哈希
  • 配置TLS/SSL
  • 管理密码学密钥
  • 实现数字签名
  • 生成随机值
  • 审核密码学实现
  • 考量后量子密码就绪性

Algorithm Quick Reference

算法速查

Encryption Algorithms

加密算法

AlgorithmTypeKey SizeUse CaseStatus
AES-256-GCMSymmetric256 bitsData encryption✅ Recommended
ChaCha20-Poly1305Symmetric256 bitsData encryption (mobile)✅ Recommended
RSA-OAEPAsymmetric2048+ bitsKey exchange✅ Recommended
ECDH (P-256)Asymmetric256 bitsKey agreement✅ Recommended
X25519Asymmetric256 bitsKey agreement✅ Recommended
DESSymmetric56 bitsNone❌ Deprecated
3DESSymmetric168 bitsLegacy only⚠️ Avoid
BlowfishSymmetric32-448 bitsNone⚠️ Avoid
算法类型密钥长度适用场景状态
AES-256-GCM对称加密256位数据加密✅ 推荐
ChaCha20-Poly1305对称加密256位数据加密(移动端)✅ 推荐
RSA-OAEP非对称加密2048+位密钥交换✅ 推荐
ECDH (P-256)非对称加密256位密钥协商✅ 推荐
X25519非对称加密256位密钥协商✅ 推荐
DES对称加密56位❌ 已弃用
3DES对称加密168位仅遗留系统⚠️ 避免使用
Blowfish对称加密32-448位⚠️ 避免使用

Signature Algorithms

签名算法

AlgorithmTypeKey SizeUse CaseStatus
Ed25519EdDSA256 bitsSignatures✅ Recommended
ECDSA (P-256)ECC256 bitsSignatures, JWT✅ Recommended
RSA-PSSRSA2048+ bitsSignatures✅ Recommended
RSA PKCS#1 v1.5RSA2048+ bitsLegacy signatures⚠️ Use PSS instead
算法类型密钥长度适用场景状态
Ed25519EdDSA256位签名✅ 推荐
ECDSA (P-256)ECC256位签名、JWT✅ 推荐
RSA-PSSRSA2048+位签名✅ 推荐
RSA PKCS#1 v1.5RSA2048+位遗留签名⚠️ 建议使用PSS替代

Hash Functions

哈希函数

AlgorithmOutput SizeUse CaseStatus
SHA-256256 bitsGeneral hashing✅ Recommended
SHA-384384 bitsHigher security✅ Recommended
SHA-512512 bitsHighest security✅ Recommended
SHA-3-256256 bitsAlternative to SHA-2✅ Recommended
BLAKE2b256-512 bitsFast hashing✅ Recommended
MD5128 bitsNone (broken)❌ Never use
SHA-1160 bitsNone (broken)❌ Never use
算法输出长度适用场景状态
SHA-256256位通用哈希✅ 推荐
SHA-384384位更高安全性需求✅ 推荐
SHA-512512位最高安全性需求✅ 推荐
SHA-3-256256位SHA-2的替代方案✅ 推荐
BLAKE2b256-512位高速哈希✅ 推荐
MD5128位无(已被破解)❌ 禁止使用
SHA-1160位无(已被破解)❌ 禁止使用

Password Hashing

密码哈希

Never use general-purpose hash functions (SHA-256, MD5) for passwords.
切勿将通用哈希函数(SHA-256、MD5)用于密码哈希。

Algorithm Comparison

算法对比

AlgorithmRecommendedMemory-HardNotes
Argon2id✅ BestYesWinner of PHC, recommended for new systems
bcrypt✅ GoodNoWidely supported, proven
scrypt✅ GoodYesGood but complex to tune
PBKDF2⚠️ AcceptableNoNIST approved, but GPU-vulnerable
算法推荐程度内存密集型说明
Argon2id✅ 最佳PHC竞赛获胜者,推荐用于新系统
bcrypt✅ 良好支持广泛,经实践验证
scrypt✅ 良好性能优秀但调参复杂
PBKDF2⚠️ 可接受NIST认可,但易受GPU攻击

Argon2id (Recommended)

Argon2id(推荐)

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

/// <summary>
/// Argon2id password hasher with OWASP 2023 recommended parameters.
/// </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>
    /// Hash password with Argon2id.
    /// </summary>
    public static string Hash(string password)
    {
        var salt = RandomNumberGenerator.GetBytes(SaltLength);
        var hash = ComputeHash(password, salt);

        // Return in PHC format: $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>
    /// Verify password against stored hash.
    /// </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)
    {
        // Parse PHC format: $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);
    }
}

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

if (Argon2PasswordHasher.Verify(hash, "user_password"))
{
    // Password valid
}
csharp
using Konscious.Security.Cryptography;
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// Argon2id password hasher with OWASP 2023 recommended parameters.
/// </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>
    /// Hash password with Argon2id.
    /// </summary>
    public static string Hash(string password)
    {
        var salt = RandomNumberGenerator.GetBytes(SaltLength);
        var hash = ComputeHash(password, salt);

        // Return in PHC format: $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>
    /// Verify password against stored hash.
    /// </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)
    {
        // Parse PHC format: $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);
    }
}

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

if (Argon2PasswordHasher.Verify(hash, "user_password"))
{
    // Password valid
}

bcrypt

bcrypt

csharp
using BCrypt.Net;

// Hash password (work factor 12 = 2^12 iterations)
var passwordHash = BCrypt.Net.BCrypt.HashPassword("user_password", workFactor: 12);

// Verify password
if (BCrypt.Net.BCrypt.Verify("user_password", passwordHash))
{
    Console.WriteLine("Password valid");
}
csharp
using BCrypt.Net;

// Hash password (work factor 12 = 2^12 iterations)
var passwordHash = BCrypt.Net.BCrypt.HashPassword("user_password", workFactor: 12);

// Verify password
if (BCrypt.Net.BCrypt.Verify("user_password", passwordHash))
{
    Console.WriteLine("Password valid");
}

Work Factor Guidelines

工作因子指南

AlgorithmMinimumRecommendedHigh Security
Argon2idt=2, m=19MBt=3, m=64MBt=4, m=128MB
bcrypt101214
scryptN=2^14N=2^16N=2^18
PBKDF2310,000600,0001,000,000
For detailed password hashing guidance: See Password Hashing Reference
算法最低要求推荐值高安全要求
Argon2idt=2, m=19MBt=3, m=64MBt=4, m=128MB
bcrypt101214
scryptN=2^14N=2^16N=2^18
PBKDF2310,000600,0001,000,000
详细密码哈希指南: 参见 Password Hashing Reference

Symmetric Encryption

对称加密

AES-256-GCM (Recommended)

AES-256-GCM(推荐)

csharp
using System.Security.Cryptography;

/// <summary>
/// AES-256-GCM encryption utilities.
/// </summary>
public static class AesGcmEncryption
{
    private const int NonceSize = 12;  // 96 bits
    private const int TagSize = 16;    // 128 bits
    private const int KeySize = 32;    // 256 bits

    /// <summary>
    /// Encrypt data with AES-256-GCM. Returns nonce + ciphertext + 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);

        // Combine: nonce + ciphertext + 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>
    /// Decrypt data with AES-256-GCM. Input is nonce + ciphertext + 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>
    /// Generate a secure 256-bit key.
    /// </summary>
    public static byte[] GenerateKey() => RandomNumberGenerator.GetBytes(KeySize);
}

// Usage
var key = AesGcmEncryption.GenerateKey();
var encrypted = AesGcmEncryption.Encrypt("sensitive data"u8, key);
var decrypted = AesGcmEncryption.Decrypt(encrypted, key);
csharp
using System.Security.Cryptography;

/// <summary>
/// AES-256-GCM encryption utilities.
/// </summary>
public static class AesGcmEncryption
{
    private const int NonceSize = 12;  // 96 bits
    private const int TagSize = 16;    // 128 bits
    private const int KeySize = 32;    // 256 bits

    /// <summary>
    /// Encrypt data with AES-256-GCM. Returns nonce + ciphertext + 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);

        // Combine: nonce + ciphertext + 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>
    /// Decrypt data with AES-256-GCM. Input is nonce + ciphertext + 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>
    /// Generate a secure 256-bit key.
    /// </summary>
    public static byte[] GenerateKey() => RandomNumberGenerator.GetBytes(KeySize);
}

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

Key Derivation from Password

从密码派生密钥

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

/// <summary>
/// Derive encryption key from password using PBKDF2.
/// </summary>
public static class KeyDerivation
{
    private const int SaltSize = 16;
    private const int KeySize = 32;  // 256 bits for AES-256
    private const int Iterations = 600000;  // OWASP 2023 recommendation

    /// <summary>
    /// Derive encryption key from password. Returns (key, salt).
    /// </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);  // Store salt with encrypted data
    }
}
csharp
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// Derive encryption key from password using PBKDF2.
/// </summary>
public static class KeyDerivation
{
    private const int SaltSize = 16;
    private const int KeySize = 32;  // 256 bits for AES-256
    private const int Iterations = 600000;  // OWASP 2023 recommendation

    /// <summary>
    /// Derive encryption key from password. Returns (key, salt).
    /// </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);  // Store salt with encrypted data
    }
}

Asymmetric Encryption

非对称加密

RSA Key Generation

RSA密钥生成

csharp
using System.Security.Cryptography;

/// <summary>
/// RSA encryption with OAEP padding.
/// </summary>
public static class RsaEncryption
{
    /// <summary>
    /// Generate RSA key pair. Use 2048 minimum; 4096 for long-term security.
    /// </summary>
    public static RSA GenerateKeyPair(int keySizeInBits = 2048)
    {
        return RSA.Create(keySizeInBits);
    }

    /// <summary>
    /// Encrypt with public key using OAEP-SHA256.
    /// </summary>
    public static byte[] Encrypt(byte[] plaintext, RSA publicKey)
    {
        return publicKey.Encrypt(plaintext, RSAEncryptionPadding.OaepSHA256);
    }

    /// <summary>
    /// Decrypt with private key using OAEP-SHA256.
    /// </summary>
    public static byte[] Decrypt(byte[] ciphertext, RSA privateKey)
    {
        return privateKey.Decrypt(ciphertext, RSAEncryptionPadding.OaepSHA256);
    }
}

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

var ciphertext = RsaEncryption.Encrypt(plaintext, rsa);
var decrypted = RsaEncryption.Decrypt(ciphertext, rsa);
csharp
using System.Security.Cryptography;

/// <summary>
/// RSA encryption with OAEP padding.
/// </summary>
public static class RsaEncryption
{
    /// <summary>
    /// Generate RSA key pair. Use 2048 minimum; 4096 for long-term security.
    /// </summary>
    public static RSA GenerateKeyPair(int keySizeInBits = 2048)
    {
        return RSA.Create(keySizeInBits);
    }

    /// <summary>
    /// Encrypt with public key using OAEP-SHA256.
    /// </summary>
    public static byte[] Encrypt(byte[] plaintext, RSA publicKey)
    {
        return publicKey.Encrypt(plaintext, RSAEncryptionPadding.OaepSHA256);
    }

    /// <summary>
    /// Decrypt with private key using OAEP-SHA256.
    /// </summary>
    public static byte[] Decrypt(byte[] ciphertext, RSA privateKey)
    {
        return privateKey.Decrypt(ciphertext, RSAEncryptionPadding.OaepSHA256);
    }
}

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

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

Digital Signatures

数字签名

csharp
using System.Security.Cryptography;

/// <summary>
/// Ed25519 digital signatures (via ECDsa with curve).
/// Note: .NET 10 has native Ed25519 support.
/// </summary>
public static class DigitalSignatures
{
    /// <summary>
    /// Create ECDSA key pair (P-256, widely supported).
    /// </summary>
    public static ECDsa CreateEcdsaKeyPair()
    {
        return ECDsa.Create(ECCurve.NamedCurves.nistP256);
    }

    /// <summary>
    /// Sign message with ECDSA-SHA256.
    /// </summary>
    public static byte[] Sign(byte[] message, ECDsa privateKey)
    {
        return privateKey.SignData(message, HashAlgorithmName.SHA256);
    }

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

// Usage
using var ecdsa = DigitalSignatures.CreateEcdsaKeyPair();

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

if (DigitalSignatures.Verify(message, signature, ecdsa))
{
    Console.WriteLine("Signature valid");
}
else
{
    Console.WriteLine("Signature invalid");
}
For detailed algorithm selection guidance: See Algorithm Selection Guide
csharp
using System.Security.Cryptography;

/// <summary>
/// Ed25519 digital signatures (via ECDsa with curve).
/// Note: .NET 10 has native Ed25519 support.
/// </summary>
public static class DigitalSignatures
{
    /// <summary>
    /// Create ECDSA key pair (P-256, widely supported).
    /// </summary>
    public static ECDsa CreateEcdsaKeyPair()
    {
        return ECDsa.Create(ECCurve.NamedCurves.nistP256);
    }

    /// <summary>
    /// Sign message with ECDSA-SHA256.
    /// </summary>
    public static byte[] Sign(byte[] message, ECDsa privateKey)
    {
        return privateKey.SignData(message, HashAlgorithmName.SHA256);
    }

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

// Usage
using var ecdsa = DigitalSignatures.CreateEcdsaKeyPair();

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

if (DigitalSignatures.Verify(message, signature, ecdsa))
{
    Console.WriteLine("Signature valid");
}
else
{
    Console.WriteLine("Signature invalid");
}
详细算法选择指南: 参见 Algorithm Selection Guide

TLS Configuration

TLS配置

Recommended TLS Settings

推荐TLS设置

nginx
undefined
nginx
undefined

Nginx TLS configuration

Nginx TLS configuration

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;
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 Strict Transport Security)

HSTS (HTTP Strict Transport Security)

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

OCSP Stapling

OCSP Stapling

ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s;
undefined
ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s;
undefined

TLS Version Requirements

TLS版本要求

VersionStatusNotes
TLS 1.3✅ RequiredBest security, improved performance
TLS 1.2✅ AcceptableStill secure with proper ciphers
TLS 1.1❌ DeprecatedDisabled since 2020
TLS 1.0❌ DeprecatedMajor vulnerabilities
SSL 3.0❌ BrokenPOODLE attack
SSL 2.0❌ BrokenMany vulnerabilities
For detailed TLS configuration: See TLS Configuration Guide
版本状态说明
TLS 1.3✅ 必需安全性最佳,性能提升
TLS 1.2✅ 可接受使用合适密码套件时仍安全
TLS 1.1❌ 已弃用2020年起已禁用
TLS 1.0❌ 已弃用存在严重漏洞
SSL 3.0❌ 已破解受POODLE攻击影响
SSL 2.0❌ 已破解存在多个漏洞
详细TLS配置指南: 参见 TLS Configuration Guide

Key Management

密钥管理

Key Hierarchy

密钥层级

text
┌─────────────────────────────────────┐
│  Master Key (KEK)                   │  <- Stored in HSM or KMS
│  - Encrypts all other keys          │
└──────────────────┬──────────────────┘
       ┌───────────┴───────────┐
       ▼                       ▼
┌──────────────┐      ┌──────────────┐
│  Data Key 1  │      │  Data Key 2  │  <- Encrypted with KEK
│  (DEK)       │      │  (DEK)       │
└──────────────┘      └──────────────┘
text
┌─────────────────────────────────────┐
│  Master Key (KEK)                   │  <- 存储于HSM或KMS
│  - 加密所有其他密钥                  │
└──────────────────┬──────────────────┘
       ┌───────────┴───────────┐
       ▼                       ▼
┌──────────────┐      ┌──────────────┐
│  Data Key 1  │      │  Data Key 2  │  <- 使用KEK加密
│  (DEK)       │      │  (DEK)       │
└──────────────┘      └──────────────┘

Key Rotation Strategy

密钥轮换策略

csharp
/// <summary>
/// Key manager with automatic rotation support.
/// </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>
    /// Get current encryption key, rotating if needed.
    /// </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)
    {
        // Create new key in KMS
        var newKey = await kmsClient.CreateKeyAsync(
            description: $"Data key created {DateTime.UtcNow:O}",
            keyUsage: KeyUsage.EncryptDecrypt,
            cancellationToken: cancellationToken
        );

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

        // Keep old keys for decryption (don't delete immediately)
        // Data encrypted with old keys can still be decrypted
    }

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

// KMS client interface (implement for Azure Key Vault, AWS KMS, etc.)
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);
csharp
/// <summary>
/// Key manager with automatic rotation support.
/// </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>
    /// Get current encryption key, rotating if needed.
    /// </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)
    {
        // Create new key in KMS
        var newKey = await kmsClient.CreateKeyAsync(
            description: $"Data key created {DateTime.UtcNow:O}",
            keyUsage: KeyUsage.EncryptDecrypt,
            cancellationToken: cancellationToken
        );

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

        // Keep old keys for decryption (don't delete immediately)
        // Data encrypted with old keys can still be decrypted
    }

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

// KMS client interface (implement for Azure Key Vault, AWS KMS, etc.)
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);

Random Number Generation

随机数生成

csharp
using System.Security.Cryptography;

// For cryptographic use - ALWAYS use these
var secureRandomBytes = RandomNumberGenerator.GetBytes(32);  // 32 random bytes
var secureRandomHex = Convert.ToHexString(RandomNumberGenerator.GetBytes(32));  // 64 hex chars
var secureRandomUrl = Convert.ToBase64String(RandomNumberGenerator.GetBytes(32))
    .Replace('+', '-').Replace('/', '_').TrimEnd('=');  // URL-safe base64

// For random integers in a range (e.g., tokens, OTPs)
var randomInt = RandomNumberGenerator.GetInt32(100000, 999999);  // 6-digit OTP

// NEVER use for cryptography
var random = new Random();
random.Next();  // NOT cryptographically secure - for games/simulations only
csharp
using System.Security.Cryptography;

// For cryptographic use - ALWAYS use these
var secureRandomBytes = RandomNumberGenerator.GetBytes(32);  // 32 random bytes
var secureRandomHex = Convert.ToHexString(RandomNumberGenerator.GetBytes(32));  // 64 hex chars
var secureRandomUrl = Convert.ToBase64String(RandomNumberGenerator.GetBytes(32))
    .Replace('+', '-').Replace('/', '_').TrimEnd('=');  // URL-safe base64

// For random integers in a range (e.g., tokens, OTPs)
var randomInt = RandomNumberGenerator.GetInt32(100000, 999999);  // 6-digit OTP

// NEVER use for cryptography
var random = new Random();
random.Next();  // NOT cryptographically secure - for games/simulations only

Post-Quantum Considerations

后量子密码考量

Current asymmetric algorithms (RSA, ECDSA, ECDH) are vulnerable to quantum computers.
当前的非对称算法(RSA、ECDSA、ECDH)易受量子计算机攻击。

NIST Post-Quantum Standards (2024)

NIST后量子标准(2024)

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

Hybrid Approach (Recommended Now)

混合方案(当前推荐)

csharp
// Combine classical and post-quantum algorithms
// If either is broken, the other still provides security

// Key exchange: X25519 + ML-KEM-768
// Signature: ECDSA P-256 + ML-DSA-65

// .NET 10+ will include ML-KEM and ML-DSA support
// Until then, use libraries like BouncyCastle for PQ algorithms

// This provides defense-in-depth during the transition period:
// 1. Classical algorithms handle today's threats
// 2. PQ algorithms protect against future quantum attacks
// 3. Combined key material ensures security if either is compromised
csharp
// Combine classical and post-quantum algorithms
// If either is broken, the other still provides security

// Key exchange: X25519 + ML-KEM-768
// Signature: ECDSA P-256 + ML-DSA-65

// .NET 10+ will include ML-KEM and ML-DSA support
// Until then, use libraries like BouncyCastle for PQ algorithms

// This provides defense-in-depth during the transition period:
// 1. Classical algorithms handle today's threats
// 2. PQ algorithms protect against future quantum attacks
// 3. Combined key material ensures security if either is compromised

Quick Decision Tree

快速决策树

What cryptographic operation do you need?
  1. Encrypt data at rest → AES-256-GCM
  2. Encrypt data in transit → TLS 1.3
  3. Hash passwords → Argon2id
  4. Hash data (non-password) → SHA-256 or BLAKE2b
  5. Digital signatures → Ed25519 or ECDSA P-256
  6. Key exchange → X25519 or ECDH P-256
  7. Message authentication → HMAC-SHA256
  8. Generate random values
    RandomNumberGenerator.GetBytes()
    or
    RandomNumberGenerator.GetInt32()
你需要哪种密码学操作?
  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()

Security Checklist

安全检查清单

Encryption

加密

  • Use authenticated encryption (AES-GCM, ChaCha20-Poly1305)
  • Generate keys with sufficient entropy (256 bits)
  • Never reuse nonces/IVs
  • Implement proper key management
  • 使用带认证的加密方式(AES-GCM、ChaCha20-Poly1305)
  • 生成具有足够熵的密钥(256位)
  • 绝不重复使用nonce/IV
  • 实现恰当的密钥管理

Password Hashing

密码哈希

  • Use Argon2id, bcrypt, or scrypt
  • Never use MD5, SHA-1, or unsalted hashes
  • Use appropriate work factors
  • Implement rehashing when parameters change
  • 使用Argon2id、bcrypt或scrypt
  • 绝不使用MD5、SHA-1或无盐哈希
  • 使用合适的工作因子
  • 当参数变更时实现重新哈希

TLS

TLS

  • TLS 1.2 minimum, prefer TLS 1.3
  • Strong cipher suites only
  • Valid certificates from trusted CA
  • Enable HSTS
  • 最低要求TLS 1.2,优先使用TLS 1.3
  • 仅使用强密码套件
  • 使用受信任CA颁发的有效证书
  • 启用HSTS

Keys

密钥

  • Secure key generation
  • Proper key storage (HSM/KMS for sensitive keys)
  • Key rotation policy
  • Secure key destruction
  • 安全生成密钥
  • 恰当存储密钥(敏感密钥存储于HSM/KMS)
  • 密钥轮换策略
  • 安全销毁密钥

References

参考资料

  • Algorithm Selection Guide - Detailed algorithm comparison
  • Password Hashing Reference - Password hashing deep dive
  • TLS Configuration Guide - TLS setup for various platforms
  • Algorithm Selection Guide - 详细算法对比
  • Password Hashing Reference - 密码哈希深度解析
  • TLS Configuration Guide - 多平台TLS配置指南

Related Skills

相关技能

SkillRelationship
authentication-patterns
Uses cryptography for JWT, sessions
secrets-management
Secure storage of cryptographic keys
secure-coding
General secure implementation patterns
技能关联关系
authentication-patterns
密码学用于JWT、会话管理
secrets-management
密码学密钥的安全存储
secure-coding
通用安全实现模式

Version History

版本历史

  • v1.0.0 (2025-12-26): Initial release with algorithms, password hashing, TLS, key management

Last Updated: 2025-12-26
  • v1.0.0 (2025-12-26): 初始版本,包含算法、密码哈希、TLS、密钥管理内容

最后更新: 2025-12-26