mcpField
C
cryptography

cryptography

github.com/melodic-softwareSecurity2888 installsUpdated today
Repository

About cryptography

cryptography is an implementation guide for developers covering encryption, password hashing, TLS, key management, and post-quantum considerations. It provides algorithm-selection guidance, examples, and security checklists.

Key features

  1. 01Symmetric and asymmetric encryption guidance
  2. 02Password-hashing algorithms and work-factor guidance
  3. 03TLS version and configuration recommendations
  4. 04Key management and rotation guidance
  5. 05Secure randomness and post-quantum considerations
  6. 06Cryptography security checklists

Use cases

  1. 01Choosing encryption for data at rest
  2. 02Implementing password storage and verification
  3. 03Configuring TLS and reviewing key management
  4. 04Assessing post-quantum readiness

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/melodic-software/claude-code-plugins --skill cryptography

After installing, type/cryptographyin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
algorithm-selection.md
password-hashing.md
tls-configuration.md

Details

From the project README

Cryptography

Comprehensive guidance for implementing cryptographic operations securely, covering encryption algorithms, password hashing, TLS, and key management.

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

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
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
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

Password Hashing

Never use general-purpose hash functions (SHA-256, MD5) for passwords.

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 (Recommended)
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
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

Symmetric Encryption

AES-256-GCM (Recommended)
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
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
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
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

TLS Configuration

Recommended TLS Settings
# 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;
TLS Version Requirements
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

Key Management

Key Hierarchy
┌─────────────────────────────────────┐
│  Master Key (KEK)                   │  <- Stored in HSM or KMS
│  - Encrypts all other keys          │
└──────────────────┬──────────────────┘
                   │
       ┌───────────┴───────────┐
       ▼                       ▼
┌──────────────┐      ┌──────────────┐
│  Data Key 1  │      │  Data Key 2  │  <- Encrypted with KEK
│  (DEK)       │      │  (DEK)       │
└──────────────┘      └──────────────┘
Key Rotation Strategy
/// <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

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.

NIST Post-Quantum Standards (2024)
AlgorithmTypeStatus
ML-KEM (Kyber)Key Encapsulation✅ Standardized
ML-DSA (Dilithium)Digital Signature✅ Standardized
SLH-DSA (SPHINCS+)Digital Signature✅ Standardized
Hybrid Approach (Recommended Now)
// 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()

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
Password Hashing
  • Use Argon2id, bcrypt, or scrypt
  • Never use MD5, SHA-1, or unsalted hashes
  • Use appropriate work factors
  • Implement rehashing when parameters change
TLS
  • TLS 1.2 minimum, prefer TLS 1.3
  • Strong cipher suites only
  • Valid certificates from trusted CA
  • Enable HSTS
Keys
  • Secure key generation
  • Proper key storage (HSM/KMS for sensitive keys)
  • Key rotation policy
  • Secure key destruction

References

Related Skills

SkillRelationship
authentication-patternsUses cryptography for JWT, sessions
secrets-managementSecure storage of cryptographic keys
secure-codingGeneral secure implementation patterns

Version History

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

Last Updated: 2025-12-26

Comments

Markdown supported