Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.

This commit is contained in:
StellaOps Bot
2025-12-26 21:54:17 +02:00
parent 335ff7da16
commit c2b9cd8d1f
3717 changed files with 264714 additions and 48202 deletions

View File

@@ -0,0 +1,488 @@
using System.Collections.Immutable;
using StellaOps.Scanner.Core.Contracts;
using StellaOps.Scanner.Emit.Cbom;
namespace StellaOps.Scanner.Analyzers.Lang.Java.Internal.Crypto;
/// <summary>
/// Extracts cryptographic assets from Java/Kotlin libraries and packages.
/// Analyzes java.security, javax.crypto, and BouncyCastle usage patterns.
/// </summary>
public sealed class JavaCryptoExtractor : ICryptoAssetExtractor
{
private static readonly ImmutableArray<string> Ecosystems = ImmutableArray.Create("maven", "gradle");
public ImmutableArray<string> SupportedEcosystems => Ecosystems;
/// <summary>
/// Known crypto-related Maven/Gradle packages.
/// </summary>
private static readonly ImmutableHashSet<string> CryptoPackages = ImmutableHashSet.Create(
StringComparer.OrdinalIgnoreCase,
// BouncyCastle
"org.bouncycastle:bcprov-jdk18on",
"org.bouncycastle:bcprov-jdk15on",
"org.bouncycastle:bcpkix-jdk18on",
"org.bouncycastle:bcpkix-jdk15on",
"org.bouncycastle:bcpg-jdk18on",
"org.bouncycastle:bctls-jdk18on",
"org.bouncycastle:bcutil-jdk18on",
// JCA/JCE providers
"org.conscrypt:conscrypt-openjdk-uber",
"com.amazon.corretto:amazon-corretto-crypto-provider",
// JWT libraries
"io.jsonwebtoken:jjwt-api",
"io.jsonwebtoken:jjwt-impl",
"com.auth0:java-jwt",
"com.nimbusds:nimbus-jose-jwt",
"org.bitbucket.b_c:jose4j",
// Password hashing
"org.mindrot:jbcrypt",
"de.mkammerer:argon2-jvm",
"com.lambdaworks:scrypt",
"at.favre.lib:bcrypt",
// TLS/SSL
"io.netty:netty-handler",
"org.eclipse.jetty:jetty-alpn-java-client",
// Crypto utilities
"commons-codec:commons-codec",
"com.google.crypto.tink:tink",
"org.apache.shiro:shiro-crypto-core",
"org.jasypt:jasypt",
"org.apache.commons:commons-crypto",
// Key management
"com.google.cloud:google-cloud-kms",
"software.amazon.awssdk:kms",
"com.azure:azure-security-keyvault-keys"
);
/// <summary>
/// Crypto provider patterns in Java.
/// </summary>
private static readonly ImmutableArray<string> CryptoProviderIndicators = ImmutableArray.Create(
"java.security",
"javax.crypto",
"org.bouncycastle",
"Security.addProvider",
"KeyStore",
"Cipher",
"MessageDigest",
"Signature",
"Mac",
"KeyGenerator",
"KeyPairGenerator",
"SecretKeyFactory",
"KeyAgreement"
);
/// <summary>
/// Algorithm patterns to detect in package names and identifiers.
/// </summary>
private static readonly ImmutableArray<CryptoAlgorithmPattern> AlgorithmPatterns = ImmutableArray.Create(
// Hash algorithms
new CryptoAlgorithmPattern("MD5", "1.2.840.113549.2.5", CryptoPrimitive.Hash, CryptoFunction.Digest, 128, IsDeprecated: true),
new CryptoAlgorithmPattern("SHA-1", "1.3.14.3.2.26", CryptoPrimitive.Hash, CryptoFunction.Digest, 160, IsDeprecated: true),
new CryptoAlgorithmPattern("SHA1", "1.3.14.3.2.26", CryptoPrimitive.Hash, CryptoFunction.Digest, 160, IsDeprecated: true),
new CryptoAlgorithmPattern("SHA-256", "2.16.840.1.101.3.4.2.1", CryptoPrimitive.Hash, CryptoFunction.Digest, 256),
new CryptoAlgorithmPattern("SHA256", "2.16.840.1.101.3.4.2.1", CryptoPrimitive.Hash, CryptoFunction.Digest, 256),
new CryptoAlgorithmPattern("SHA-384", "2.16.840.1.101.3.4.2.2", CryptoPrimitive.Hash, CryptoFunction.Digest, 384),
new CryptoAlgorithmPattern("SHA-512", "2.16.840.1.101.3.4.2.3", CryptoPrimitive.Hash, CryptoFunction.Digest, 512),
new CryptoAlgorithmPattern("SHA-3", "2.16.840.1.101.3.4.2.8", CryptoPrimitive.Hash, CryptoFunction.Digest, 256),
new CryptoAlgorithmPattern("SHA3-256", "2.16.840.1.101.3.4.2.8", CryptoPrimitive.Hash, CryptoFunction.Digest, 256),
new CryptoAlgorithmPattern("SHA3-512", "2.16.840.1.101.3.4.2.10", CryptoPrimitive.Hash, CryptoFunction.Digest, 512),
new CryptoAlgorithmPattern("BLAKE2", null, CryptoPrimitive.Hash, CryptoFunction.Digest, 256),
new CryptoAlgorithmPattern("BLAKE3", null, CryptoPrimitive.Hash, CryptoFunction.Digest, 256),
// Symmetric ciphers
new CryptoAlgorithmPattern("AES", "2.16.840.1.101.3.4.1", CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 256),
new CryptoAlgorithmPattern("AES/GCM", "2.16.840.1.101.3.4.1.46", CryptoPrimitive.Aead, CryptoFunction.Encrypt, 256),
new CryptoAlgorithmPattern("AES/CBC", "2.16.840.1.101.3.4.1.2", CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 256),
new CryptoAlgorithmPattern("AES/CTR", "2.16.840.1.101.3.4.1.42", CryptoPrimitive.StreamCipher, CryptoFunction.Encrypt, 256),
new CryptoAlgorithmPattern("DES", "1.3.14.3.2.7", CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 56, IsDeprecated: true),
new CryptoAlgorithmPattern("DESede", "1.2.840.113549.3.7", CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 168, IsWeak: true),
new CryptoAlgorithmPattern("3DES", "1.2.840.113549.3.7", CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 168, IsWeak: true),
new CryptoAlgorithmPattern("TripleDES", "1.2.840.113549.3.7", CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 168, IsWeak: true),
new CryptoAlgorithmPattern("Blowfish", null, CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 128, IsWeak: true),
new CryptoAlgorithmPattern("RC4", null, CryptoPrimitive.StreamCipher, CryptoFunction.Encrypt, 128, IsDeprecated: true),
new CryptoAlgorithmPattern("RC2", null, CryptoPrimitive.BlockCipher, CryptoFunction.Encrypt, 128, IsDeprecated: true),
new CryptoAlgorithmPattern("ChaCha20", null, CryptoPrimitive.StreamCipher, CryptoFunction.Encrypt, 256),
new CryptoAlgorithmPattern("ChaCha20-Poly1305", null, CryptoPrimitive.Aead, CryptoFunction.Encrypt, 256),
new CryptoAlgorithmPattern("XChaCha20", null, CryptoPrimitive.StreamCipher, CryptoFunction.Encrypt, 256),
// Asymmetric algorithms
new CryptoAlgorithmPattern("RSA", "1.2.840.113549.1.1.1", CryptoPrimitive.Rsa, CryptoFunction.Sign, 2048, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("DSA", "1.2.840.10040.4.1", CryptoPrimitive.Dlog, CryptoFunction.Sign, 2048, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("EC", "1.2.840.10045.2.1", CryptoPrimitive.Ec, CryptoFunction.Sign, 256, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("ECDSA", "1.2.840.10045.4.3", CryptoPrimitive.Ec, CryptoFunction.Sign, 256, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("ECDH", "1.3.132.1.12", CryptoPrimitive.Ec, CryptoFunction.KeyAgree, 256, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("Ed25519", "1.3.101.112", CryptoPrimitive.Ec, CryptoFunction.Sign, 256, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("Ed448", "1.3.101.113", CryptoPrimitive.Ec, CryptoFunction.Sign, 448, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("X25519", "1.3.101.110", CryptoPrimitive.Ec, CryptoFunction.KeyAgree, 256, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("X448", "1.3.101.111", CryptoPrimitive.Ec, CryptoFunction.KeyAgree, 448, IsQuantumVulnerable: true),
new CryptoAlgorithmPattern("DiffieHellman", null, CryptoPrimitive.Dlog, CryptoFunction.KeyAgree, 2048, IsQuantumVulnerable: true),
// Key derivation
new CryptoAlgorithmPattern("PBKDF2", "1.2.840.113549.1.5.12", CryptoPrimitive.Pbkdf, CryptoFunction.Derive, 256),
new CryptoAlgorithmPattern("HKDF", null, CryptoPrimitive.Kdf, CryptoFunction.Derive, 256),
new CryptoAlgorithmPattern("BCrypt", null, CryptoPrimitive.Pbkdf, CryptoFunction.Derive, 184),
new CryptoAlgorithmPattern("SCrypt", null, CryptoPrimitive.Pbkdf, CryptoFunction.Derive, 256),
new CryptoAlgorithmPattern("Argon2", null, CryptoPrimitive.Pbkdf, CryptoFunction.Derive, 256),
new CryptoAlgorithmPattern("Argon2id", null, CryptoPrimitive.Pbkdf, CryptoFunction.Derive, 256),
// MACs
new CryptoAlgorithmPattern("HmacSHA256", "1.2.840.113549.2.9", CryptoPrimitive.Mac, CryptoFunction.Tag, 256),
new CryptoAlgorithmPattern("HmacSHA384", "1.2.840.113549.2.10", CryptoPrimitive.Mac, CryptoFunction.Tag, 384),
new CryptoAlgorithmPattern("HmacSHA512", "1.2.840.113549.2.11", CryptoPrimitive.Mac, CryptoFunction.Tag, 512),
new CryptoAlgorithmPattern("HmacMD5", "1.3.6.1.5.5.8.1.1", CryptoPrimitive.Mac, CryptoFunction.Tag, 128, IsDeprecated: true),
new CryptoAlgorithmPattern("HmacSHA1", "1.2.840.113549.2.7", CryptoPrimitive.Mac, CryptoFunction.Tag, 160, IsDeprecated: true),
new CryptoAlgorithmPattern("Poly1305", null, CryptoPrimitive.Mac, CryptoFunction.Tag, 128),
new CryptoAlgorithmPattern("GMAC", null, CryptoPrimitive.Mac, CryptoFunction.Tag, 128),
// Post-quantum (BouncyCastle implementations)
new CryptoAlgorithmPattern("Kyber", null, CryptoPrimitive.Kem, CryptoFunction.Encapsulate, 256, IsPostQuantum: true),
new CryptoAlgorithmPattern("ML-KEM", null, CryptoPrimitive.Kem, CryptoFunction.Encapsulate, 256, IsPostQuantum: true),
new CryptoAlgorithmPattern("Dilithium", null, CryptoPrimitive.Lattice, CryptoFunction.Sign, 256, IsPostQuantum: true),
new CryptoAlgorithmPattern("ML-DSA", null, CryptoPrimitive.Lattice, CryptoFunction.Sign, 256, IsPostQuantum: true),
new CryptoAlgorithmPattern("SPHINCS+", null, CryptoPrimitive.Hash, CryptoFunction.Sign, 256, IsPostQuantum: true),
new CryptoAlgorithmPattern("SLH-DSA", null, CryptoPrimitive.Hash, CryptoFunction.Sign, 256, IsPostQuantum: true),
new CryptoAlgorithmPattern("NTRU", null, CryptoPrimitive.Lattice, CryptoFunction.Encapsulate, 256, IsPostQuantum: true),
new CryptoAlgorithmPattern("FrodoKEM", null, CryptoPrimitive.Kem, CryptoFunction.Encapsulate, 256, IsPostQuantum: true)
);
public Task<ImmutableArray<CryptoAsset>> ExtractAsync(
AggregatedComponent component,
CryptoAnalysisContext analysisContext,
CancellationToken cancellationToken = default)
{
var assets = new List<CryptoAsset>();
var packageName = component.Identity.Name ?? string.Empty;
var purl = component.Identity.Purl ?? string.Empty;
// Skip if not a Java package
if (!purl.StartsWith("pkg:maven/", StringComparison.OrdinalIgnoreCase) &&
!purl.StartsWith("pkg:gradle/", StringComparison.OrdinalIgnoreCase))
{
return Task.FromResult(ImmutableArray<CryptoAsset>.Empty);
}
// Check for known crypto packages by group:artifact format
var groupArtifact = ExtractGroupArtifact(purl);
if (CryptoPackages.Contains(groupArtifact))
{
var cryptoAssets = ExtractFromKnownPackage(component, groupArtifact);
assets.AddRange(cryptoAssets);
}
// Check package name for algorithm patterns
foreach (var pattern in AlgorithmPatterns)
{
if (packageName.Contains(pattern.Name, StringComparison.OrdinalIgnoreCase) ||
groupArtifact.Contains(pattern.Name, StringComparison.OrdinalIgnoreCase))
{
var asset = CreateAssetFromPattern(component, pattern);
if (!assets.Any(a => a.AlgorithmName == asset.AlgorithmName))
{
assets.Add(asset);
}
}
}
// Check metadata for crypto provider evidence
if (component.Metadata?.Properties != null)
{
foreach (var (key, value) in component.Metadata.Properties)
{
// Check for crypto provider indicators
foreach (var indicator in CryptoProviderIndicators)
{
if (value.Contains(indicator, StringComparison.OrdinalIgnoreCase))
{
// Look for specific algorithms
foreach (var pattern in AlgorithmPatterns)
{
if (value.Contains(pattern.Name, StringComparison.OrdinalIgnoreCase))
{
var asset = CreateAssetFromPattern(component, pattern, $"property:{key}");
if (!assets.Any(a => a.AlgorithmName == asset.AlgorithmName))
{
assets.Add(asset);
}
}
}
break;
}
}
}
}
return Task.FromResult(assets.ToImmutableArray());
}
private static string ExtractGroupArtifact(string purl)
{
// Extract group:artifact from pkg:maven/group/artifact@version
var prefix = purl.StartsWith("pkg:maven/", StringComparison.OrdinalIgnoreCase) ? "pkg:maven/" :
purl.StartsWith("pkg:gradle/", StringComparison.OrdinalIgnoreCase) ? "pkg:gradle/" : null;
if (prefix == null) return string.Empty;
var rest = purl[prefix.Length..];
var versionIdx = rest.IndexOf('@');
if (versionIdx > 0)
{
rest = rest[..versionIdx];
}
// Replace / with : for group:artifact format
return rest.Replace('/', ':');
}
private static IEnumerable<CryptoAsset> ExtractFromKnownPackage(AggregatedComponent component, string groupArtifact)
{
var assets = new List<CryptoAsset>();
if (groupArtifact.Contains("bouncycastle", StringComparison.OrdinalIgnoreCase))
{
// BouncyCastle provides comprehensive crypto
var bcAlgorithms = AlgorithmPatterns.Where(p =>
p.Name == "AES" || p.Name == "RSA" || p.Name == "ECDSA" ||
p.Name == "SHA-256" || p.Name == "SHA-512" || p.Name == "ChaCha20-Poly1305" ||
p.Name == "Ed25519" || p.Name == "X25519" || p.IsPostQuantum);
foreach (var pattern in bcAlgorithms)
{
assets.Add(CreateAssetFromPattern(component, pattern, $"package:{groupArtifact}",
implementationPlatform: "BouncyCastle"));
}
}
else if (groupArtifact.Contains("jjwt", StringComparison.OrdinalIgnoreCase) ||
groupArtifact.Contains("java-jwt", StringComparison.OrdinalIgnoreCase) ||
groupArtifact.Contains("nimbus-jose-jwt", StringComparison.OrdinalIgnoreCase) ||
groupArtifact.Contains("jose4j", StringComparison.OrdinalIgnoreCase))
{
// JWT libraries use various algorithms
var jwtAlgorithms = new[]
{
AlgorithmPatterns.First(p => p.Name == "RSA"),
AlgorithmPatterns.First(p => p.Name == "ECDSA"),
AlgorithmPatterns.First(p => p.Name == "HmacSHA256"),
AlgorithmPatterns.First(p => p.Name == "HmacSHA512"),
AlgorithmPatterns.First(p => p.Name == "Ed25519"),
AlgorithmPatterns.First(p => p.Name == "AES/GCM")
};
foreach (var pattern in jwtAlgorithms)
{
assets.Add(CreateAssetFromPattern(component, pattern, $"package:{groupArtifact}"));
}
}
else if (groupArtifact.Contains("jbcrypt", StringComparison.OrdinalIgnoreCase) ||
groupArtifact.Contains("bcrypt", StringComparison.OrdinalIgnoreCase))
{
assets.Add(CreateAssetFromPattern(component,
AlgorithmPatterns.First(p => p.Name == "BCrypt"), $"package:{groupArtifact}"));
}
else if (groupArtifact.Contains("argon2", StringComparison.OrdinalIgnoreCase))
{
assets.Add(CreateAssetFromPattern(component,
AlgorithmPatterns.First(p => p.Name == "Argon2id"), $"package:{groupArtifact}"));
}
else if (groupArtifact.Contains("scrypt", StringComparison.OrdinalIgnoreCase))
{
assets.Add(CreateAssetFromPattern(component,
AlgorithmPatterns.First(p => p.Name == "SCrypt"), $"package:{groupArtifact}"));
}
else if (groupArtifact.Contains("tink", StringComparison.OrdinalIgnoreCase))
{
// Google Tink provides modern crypto
var tinkAlgorithms = new[]
{
AlgorithmPatterns.First(p => p.Name == "AES/GCM"),
AlgorithmPatterns.First(p => p.Name == "ChaCha20-Poly1305"),
AlgorithmPatterns.First(p => p.Name == "ECDSA"),
AlgorithmPatterns.First(p => p.Name == "Ed25519"),
AlgorithmPatterns.First(p => p.Name == "HKDF")
};
foreach (var pattern in tinkAlgorithms)
{
assets.Add(CreateAssetFromPattern(component, pattern, $"package:{groupArtifact}",
implementationPlatform: "Google Tink"));
}
}
else if (groupArtifact.Contains("conscrypt", StringComparison.OrdinalIgnoreCase))
{
// Conscrypt OpenSSL-based provider
var conscryptAlgorithms = new[]
{
AlgorithmPatterns.First(p => p.Name == "AES/GCM"),
AlgorithmPatterns.First(p => p.Name == "ChaCha20-Poly1305"),
AlgorithmPatterns.First(p => p.Name == "SHA-256"),
AlgorithmPatterns.First(p => p.Name == "RSA"),
AlgorithmPatterns.First(p => p.Name == "ECDSA")
};
foreach (var pattern in conscryptAlgorithms)
{
assets.Add(CreateAssetFromPattern(component, pattern, $"package:{groupArtifact}",
implementationPlatform: "Conscrypt/OpenSSL"));
}
}
else if (groupArtifact.Contains("amazon-corretto-crypto", StringComparison.OrdinalIgnoreCase))
{
// Amazon Corretto Crypto Provider
var acpAlgorithms = new[]
{
AlgorithmPatterns.First(p => p.Name == "AES/GCM"),
AlgorithmPatterns.First(p => p.Name == "SHA-256"),
AlgorithmPatterns.First(p => p.Name == "SHA-512"),
AlgorithmPatterns.First(p => p.Name == "RSA"),
AlgorithmPatterns.First(p => p.Name == "ECDSA"),
AlgorithmPatterns.First(p => p.Name == "ECDH")
};
foreach (var pattern in acpAlgorithms)
{
assets.Add(CreateAssetFromPattern(component, pattern, $"package:{groupArtifact}",
implementationPlatform: "Amazon Corretto Crypto Provider"));
}
}
else if (groupArtifact.Contains("kms", StringComparison.OrdinalIgnoreCase))
{
// Cloud KMS libraries
assets.Add(new CryptoAsset
{
Id = $"crypto:{component.Identity.Key}:kms",
ComponentKey = component.Identity.Key,
AssetType = CryptoAssetType.RelatedCryptoMaterial,
AlgorithmName = "KMS",
Confidence = 0.9,
ImplementationPlatform = groupArtifact.Contains("google") ? "Google Cloud KMS" :
groupArtifact.Contains("aws") ? "AWS KMS" :
groupArtifact.Contains("azure") ? "Azure Key Vault" : "Cloud KMS",
Evidence = ImmutableArray.Create($"package:{groupArtifact}")
});
}
return assets;
}
private static CryptoAsset CreateAssetFromPattern(
AggregatedComponent component,
CryptoAlgorithmPattern pattern,
string? evidenceSource = null,
string? implementationPlatform = null)
{
var riskFlags = new List<CryptoRiskFlag>();
if (pattern.IsDeprecated)
{
riskFlags.Add(new CryptoRiskFlag
{
RiskId = "DEPRECATED_ALGORITHM",
Severity = CryptoRiskSeverity.Critical,
Description = $"{pattern.Name} is deprecated and should not be used",
Recommendation = GetDeprecatedRecommendation(pattern.Name)
});
}
if (pattern.IsWeak)
{
riskFlags.Add(new CryptoRiskFlag
{
RiskId = "WEAK_ALGORITHM",
Severity = CryptoRiskSeverity.High,
Description = $"{pattern.Name} is considered weak by modern standards",
Recommendation = GetWeakRecommendation(pattern.Name)
});
}
if (pattern.IsQuantumVulnerable)
{
riskFlags.Add(new CryptoRiskFlag
{
RiskId = "QUANTUM_VULNERABLE",
Severity = CryptoRiskSeverity.Medium,
Description = $"{pattern.Name} is vulnerable to quantum computing attacks",
Recommendation = "Consider migration path to post-quantum algorithms (ML-KEM, ML-DSA, SLH-DSA)"
});
}
var evidence = new List<string> { $"component:{component.Identity.Key}" };
if (evidenceSource != null)
{
evidence.Add(evidenceSource);
}
var platform = implementationPlatform ?? "Java Cryptography Architecture (JCA)";
var algorithmProperties = new AlgorithmProperties
{
Primitive = pattern.Primitive,
CryptoFunctions = ImmutableArray.Create(pattern.Function),
ClassicalSecurityLevel = pattern.KeySize,
ImplementationPlatform = platform,
ExecutionEnvironment = ExecutionEnvironment.Software
};
return new CryptoAsset
{
Id = $"crypto:{component.Identity.Key}:{pattern.Name}",
ComponentKey = component.Identity.Key,
AssetType = CryptoAssetType.Algorithm,
AlgorithmName = pattern.Name,
Oid = pattern.Oid,
KeySizeBits = pattern.KeySize,
Primitive = pattern.Primitive,
Functions = ImmutableArray.Create(pattern.Function),
ImplementationPlatform = platform,
ExecutionEnvironment = ExecutionEnvironment.Software,
Confidence = 0.9,
Evidence = evidence.ToImmutableArray(),
RiskFlags = riskFlags.ToImmutableArray(),
CryptoProperties = new CryptoProperties
{
AssetType = CryptoAssetType.Algorithm,
AlgorithmProperties = algorithmProperties,
Oid = pattern.Oid
}
};
}
private static string GetDeprecatedRecommendation(string algorithm)
{
return algorithm.ToUpperInvariant() switch
{
"MD5" => "Replace with SHA-256 or SHA-3",
"SHA1" or "SHA-1" => "Replace with SHA-256 or SHA-3",
"DES" => "Replace with AES-256-GCM",
"RC4" => "Replace with ChaCha20-Poly1305 or AES-GCM",
"RC2" => "Replace with AES-256-GCM",
"HMACMD5" => "Replace with HmacSHA256",
"HMACSHA1" => "Replace with HmacSHA256",
_ => "Replace with a modern algorithm"
};
}
private static string GetWeakRecommendation(string algorithm)
{
return algorithm.ToUpperInvariant() switch
{
"DESEDE" or "3DES" or "TRIPLEDES" => "Replace with AES-256-GCM",
"BLOWFISH" => "Replace with AES-256-GCM or ChaCha20-Poly1305",
_ => "Consider using a stronger algorithm"
};
}
private sealed record CryptoAlgorithmPattern(
string Name,
string? Oid,
CryptoPrimitive Primitive,
CryptoFunction Function,
int KeySize,
bool IsDeprecated = false,
bool IsWeak = false,
bool IsQuantumVulnerable = false,
bool IsPostQuantum = false);
}

View File

@@ -16,5 +16,6 @@
<ItemGroup>
<ProjectReference Include="..\StellaOps.Scanner.Analyzers.Lang\StellaOps.Scanner.Analyzers.Lang.csproj" />
<ProjectReference Include="..\StellaOps.Scanner.Emit\StellaOps.Scanner.Emit.csproj" />
</ItemGroup>
</Project>