129 lines
4.4 KiB
C#
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);
|