cryptography
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCryptography
密码学
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
加密算法
| Algorithm | Type | Key Size | Use Case | Status |
|---|---|---|---|---|
| AES-256-GCM | Symmetric | 256 bits | Data encryption | ✅ Recommended |
| ChaCha20-Poly1305 | Symmetric | 256 bits | Data encryption (mobile) | ✅ Recommended |
| RSA-OAEP | Asymmetric | 2048+ bits | Key exchange | ✅ Recommended |
| ECDH (P-256) | Asymmetric | 256 bits | Key agreement | ✅ Recommended |
| X25519 | Asymmetric | 256 bits | Key agreement | ✅ Recommended |
| DES | Symmetric | 56 bits | None | ❌ Deprecated |
| 3DES | Symmetric | 168 bits | Legacy only | ⚠️ Avoid |
| Blowfish | Symmetric | 32-448 bits | None | ⚠️ 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
签名算法
| Algorithm | Type | Key Size | Use Case | Status |
|---|---|---|---|---|
| Ed25519 | EdDSA | 256 bits | Signatures | ✅ Recommended |
| ECDSA (P-256) | ECC | 256 bits | Signatures, JWT | ✅ Recommended |
| RSA-PSS | RSA | 2048+ bits | Signatures | ✅ Recommended |
| RSA PKCS#1 v1.5 | RSA | 2048+ bits | Legacy signatures | ⚠️ Use PSS instead |
| 算法 | 类型 | 密钥长度 | 适用场景 | 状态 |
|---|---|---|---|---|
| Ed25519 | EdDSA | 256位 | 签名 | ✅ 推荐 |
| ECDSA (P-256) | ECC | 256位 | 签名、JWT | ✅ 推荐 |
| RSA-PSS | RSA | 2048+位 | 签名 | ✅ 推荐 |
| RSA PKCS#1 v1.5 | RSA | 2048+位 | 遗留签名 | ⚠️ 建议使用PSS替代 |
Hash Functions
哈希函数
| Algorithm | Output Size | Use Case | Status |
|---|---|---|---|
| SHA-256 | 256 bits | General hashing | ✅ Recommended |
| SHA-384 | 384 bits | Higher security | ✅ Recommended |
| SHA-512 | 512 bits | Highest security | ✅ Recommended |
| SHA-3-256 | 256 bits | Alternative to SHA-2 | ✅ Recommended |
| BLAKE2b | 256-512 bits | Fast hashing | ✅ Recommended |
| MD5 | 128 bits | None (broken) | ❌ Never use |
| SHA-1 | 160 bits | None (broken) | ❌ Never use |
| 算法 | 输出长度 | 适用场景 | 状态 |
|---|---|---|---|
| SHA-256 | 256位 | 通用哈希 | ✅ 推荐 |
| SHA-384 | 384位 | 更高安全性需求 | ✅ 推荐 |
| SHA-512 | 512位 | 最高安全性需求 | ✅ 推荐 |
| SHA-3-256 | 256位 | SHA-2的替代方案 | ✅ 推荐 |
| BLAKE2b | 256-512位 | 高速哈希 | ✅ 推荐 |
| MD5 | 128位 | 无(已被破解) | ❌ 禁止使用 |
| SHA-1 | 160位 | 无(已被破解) | ❌ 禁止使用 |
Password Hashing
密码哈希
Never use general-purpose hash functions (SHA-256, MD5) for passwords.
切勿将通用哈希函数(SHA-256、MD5)用于密码哈希。
Algorithm Comparison
算法对比
| Algorithm | Recommended | Memory-Hard | Notes |
|---|---|---|---|
| Argon2id | ✅ Best | Yes | Winner of PHC, recommended for new systems |
| bcrypt | ✅ Good | No | Widely supported, proven |
| scrypt | ✅ Good | Yes | Good but complex to tune |
| PBKDF2 | ⚠️ Acceptable | No | NIST 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
工作因子指南
| Algorithm | Minimum | Recommended | High Security |
|---|---|---|---|
| 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 |
For detailed password hashing guidance: See Password Hashing Reference
| 算法 | 最低要求 | 推荐值 | 高安全要求 |
|---|---|---|---|
| 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 |
详细密码哈希指南: 参见 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
undefinednginx
undefinedNginx 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;
undefinedssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
undefinedTLS Version Requirements
TLS版本要求
| Version | Status | Notes |
|---|---|---|
| TLS 1.3 | ✅ Required | Best security, improved performance |
| TLS 1.2 | ✅ Acceptable | Still secure with proper ciphers |
| TLS 1.1 | ❌ Deprecated | Disabled since 2020 |
| TLS 1.0 | ❌ Deprecated | Major vulnerabilities |
| SSL 3.0 | ❌ Broken | POODLE attack |
| SSL 2.0 | ❌ Broken | Many 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 onlycsharp
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 onlyPost-Quantum Considerations
后量子密码考量
Current asymmetric algorithms (RSA, ECDSA, ECDH) are vulnerable to quantum computers.
当前的非对称算法(RSA、ECDSA、ECDH)易受量子计算机攻击。
NIST Post-Quantum Standards (2024)
NIST后量子标准(2024)
| Algorithm | Type | Status |
|---|---|---|
| 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 compromisedcsharp
// 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 compromisedQuick Decision Tree
快速决策树
What cryptographic operation do you need?
- Encrypt data at rest → AES-256-GCM
- Encrypt data in transit → TLS 1.3
- Hash passwords → Argon2id
- Hash data (non-password) → SHA-256 or BLAKE2b
- Digital signatures → Ed25519 or ECDSA P-256
- Key exchange → X25519 or ECDH P-256
- Message authentication → HMAC-SHA256
- Generate random values → or
RandomNumberGenerator.GetBytes()RandomNumberGenerator.GetInt32()
你需要哪种密码学操作?
- 加密静态数据 → AES-256-GCM
- 加密传输中数据 → TLS 1.3
- 哈希密码 → Argon2id
- 哈希数据(非密码) → SHA-256或BLAKE2b
- 数字签名 → Ed25519或ECDSA P-256
- 密钥交换 → X25519或ECDH P-256
- 消息认证 → HMAC-SHA256
- 生成随机值 → 或
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
相关技能
| Skill | Relationship |
|---|---|
| Uses cryptography for JWT, sessions |
| Secure storage of cryptographic keys |
| General secure implementation patterns |
| 技能 | 关联关系 |
|---|---|
| 密码学用于JWT、会话管理 |
| 密码学密钥的安全存储 |
| 通用安全实现模式 |
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