Files
git.stella-ops.org/devops/services/crypto/sim-crypto-service/Program.cs
2025-12-26 18:11:06 +02:00

129 lines
4.4 KiB
C#

using System.Security.Cryptography;
using System.Text;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Static key material for simulations (not for production use).
using var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
var ecdsaPublic = ecdsa.ExportSubjectPublicKeyInfo();
byte[] Sign(string message, string algorithm)
{
var data = Encoding.UTF8.GetBytes(message);
var lower = algorithm.Trim().ToLowerInvariant();
var upper = algorithm.Trim().ToUpperInvariant();
if (lower is "pq.dilithium3" or "pq.falcon512" or "pq.sim" || upper is "DILITHIUM3" or "FALCON512")
{
return HMACSHA256.HashData(Encoding.UTF8.GetBytes("pq-sim-key"), data);
}
if (lower is "ru.magma.sim" or "ru.kuznyechik.sim" || upper is "GOST12-256" or "GOST12-512")
{
return HMACSHA256.HashData(Encoding.UTF8.GetBytes("gost-sim-key"), data);
}
if (lower is "sm.sim" or "sm2.sim" || upper is "SM2")
{
return HMACSHA256.HashData(Encoding.UTF8.GetBytes("sm-sim-key"), data);
}
return ecdsa.SignData(data, HashAlgorithmName.SHA256);
}
bool Verify(string message, string algorithm, byte[] signature)
{
var data = Encoding.UTF8.GetBytes(message);
var lower = algorithm.Trim().ToLowerInvariant();
var upper = algorithm.Trim().ToUpperInvariant();
if (lower is "pq.dilithium3" or "pq.falcon512" or "pq.sim" || upper is "DILITHIUM3" or "FALCON512")
{
return CryptographicOperations.FixedTimeEquals(HMACSHA256.HashData(Encoding.UTF8.GetBytes("pq-sim-key"), data), signature);
}
if (lower is "ru.magma.sim" or "ru.kuznyechik.sim" || upper is "GOST12-256" or "GOST12-512")
{
return CryptographicOperations.FixedTimeEquals(HMACSHA256.HashData(Encoding.UTF8.GetBytes("gost-sim-key"), data), signature);
}
if (lower is "sm.sim" or "sm2.sim" || upper is "SM2")
{
return CryptographicOperations.FixedTimeEquals(HMACSHA256.HashData(Encoding.UTF8.GetBytes("sm-sim-key"), data), signature);
}
return ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA256);
}
app.MapPost("/sign", (SignRequest request) =>
{
if (string.IsNullOrWhiteSpace(request.Algorithm) || string.IsNullOrWhiteSpace(request.Message))
{
return Results.BadRequest("Algorithm and message are required.");
}
var sig = Sign(request.Message, request.Algorithm);
return Results.Json(new SignResponse(Convert.ToBase64String(sig), request.Algorithm));
});
app.MapPost("/verify", (VerifyRequest request) =>
{
if (string.IsNullOrWhiteSpace(request.Algorithm) || string.IsNullOrWhiteSpace(request.Message) || string.IsNullOrWhiteSpace(request.SignatureBase64))
{
return Results.BadRequest("Algorithm, message, and signature are required.");
}
var sig = Convert.FromBase64String(request.SignatureBase64);
var ok = Verify(request.Message, request.Algorithm, sig);
return Results.Json(new VerifyResponse(ok, request.Algorithm));
});
app.MapGet("/keys", () =>
{
return Results.Json(new KeysResponse(
Convert.ToBase64String(ecdsaPublic),
"nistp256",
new[]
{
"pq.sim",
"DILITHIUM3",
"FALCON512",
"ru.magma.sim",
"ru.kuznyechik.sim",
"GOST12-256",
"GOST12-512",
"sm.sim",
"SM2",
"fips.sim",
"eidas.sim",
"kcmvp.sim",
"world.sim"
}));
});
app.Run();
public record SignRequest(
[property: JsonPropertyName("message")] string Message,
[property: JsonPropertyName("algorithm")] string Algorithm);
public record SignResponse(
[property: JsonPropertyName("signature_b64")] string SignatureBase64,
[property: JsonPropertyName("algorithm")] string Algorithm);
public record VerifyRequest(
[property: JsonPropertyName("message")] string Message,
[property: JsonPropertyName("signature_b64")] string SignatureBase64,
[property: JsonPropertyName("algorithm")] string Algorithm);
public record VerifyResponse(
[property: JsonPropertyName("ok")] bool Ok,
[property: JsonPropertyName("algorithm")] string Algorithm);
public record KeysResponse(
[property: JsonPropertyName("public_key_b64")] string PublicKeyBase64,
[property: JsonPropertyName("curve")] string Curve,
[property: JsonPropertyName("simulated_providers")] IEnumerable<string> Providers);