Comprehensive cryptography guidance covering encryption algorithms, password hashing, TLS configuration, key management, and post-quantum considerations. Use when implementing encryption, choosing hashing algorithms, configuring TLS/SSL, managing cryptographic keys, or reviewing cryptographic implementations.
Provides comprehensive cryptography guidance for implementing encryption, password hashing, TLS, and key management securely. Use when choosing algorithms like AES-256-GCM or Argon2id, configuring TLS 1.3, or reviewing cryptographic implementations.
/plugin marketplace add melodic-software/claude-code-plugins/plugin install security@melodic-softwareThis skill is limited to using the following tools:
references/algorithm-selection.mdreferences/password-hashing.mdreferences/tls-configuration.mdComprehensive guidance for implementing cryptographic operations securely, covering encryption algorithms, password hashing, TLS, and key management.
Use this skill when:
| 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 |
| 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 |
| 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 |
Never use general-purpose hash functions (SHA-256, MD5) for passwords.
| 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 |
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
}
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");
}
| 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
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);
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
}
}
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);
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
# 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;
# HSTS (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
| 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
┌─────────────────────────────────────┐
│ Master Key (KEK) │ <- Stored in HSM or KMS
│ - Encrypts all other keys │
└──────────────────┬──────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Data Key 1 │ │ Data Key 2 │ <- Encrypted with KEK
│ (DEK) │ │ (DEK) │
└──────────────┘ └──────────────┘
/// <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);
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
Current asymmetric algorithms (RSA, ECDSA, ECDH) are vulnerable to quantum computers.
| Algorithm | Type | Status |
|---|---|---|
| ML-KEM (Kyber) | Key Encapsulation | ✅ Standardized |
| ML-DSA (Dilithium) | Digital Signature | ✅ Standardized |
| SLH-DSA (SPHINCS+) | Digital Signature | ✅ Standardized |
// 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
What cryptographic operation do you need?
RandomNumberGenerator.GetBytes() or RandomNumberGenerator.GetInt32()| Skill | Relationship |
|---|---|
authentication-patterns | Uses cryptography for JWT, sessions |
secrets-management | Secure storage of cryptographic keys |
secure-coding | General secure implementation patterns |
Last Updated: 2025-12-26
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.