MST

星途 面试题库

面试题:C#数据安全实践之防止重放攻击

在C#开发的Web应用中,如何防止重放攻击?请给出具体实现思路并结合代码示例说明,同时阐述重放攻击对数据安全的威胁。
32.8万 热度难度
编程语言C#

知识考点

AI 面试

面试题答案

一键面试

防止重放攻击的实现思路

  1. 使用时间戳:在请求中添加时间戳,服务器验证时间戳是否在合理时间范围内。若超出范围,认定为可能的重放攻击。
  2. 使用随机数(Nonce):每次请求生成唯一随机数,服务器记录已使用的随机数,若再次接收到相同随机数,判定为重放攻击。
  3. 结合签名:对请求数据(包括时间戳或随机数)进行签名,服务器通过验证签名来确保请求未被篡改。

代码示例

  1. 使用时间戳
public class TimestampMiddleware
{
    private readonly RequestDelegate _next;
    private const int MaxTimeDifferenceInSeconds = 300; // 5分钟

    public TimestampMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Headers.TryGetValue("Timestamp", out var timestampHeader))
        {
            if (long.TryParse(timestampHeader, out var timestamp))
            {
                var currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                if (Math.Abs(currentTime - timestamp) > MaxTimeDifferenceInSeconds)
                {
                    context.Response.StatusCode = 400;
                    await context.Response.WriteAsync("Invalid timestamp, possible replay attack.");
                    return;
                }
            }
            else
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Invalid timestamp format.");
                return;
            }
        }
        else
        {
            context.Response.StatusCode = 400;
            await context.Response.WriteAsync("Timestamp header is missing.");
            return;
        }

        await _next(context);
    }
}

Startup.cs 中注册中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<TimestampMiddleware>();
    // 其他配置
}
  1. 使用随机数(Nonce)
private static HashSet<string> usedNonces = new HashSet<string>();

public class NonceMiddleware
{
    private readonly RequestDelegate _next;

    public NonceMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Headers.TryGetValue("Nonce", out var nonceHeader))
        {
            if (usedNonces.Contains(nonceHeader))
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Duplicate nonce, possible replay attack.");
                return;
            }
            else
            {
                usedNonces.Add(nonceHeader);
            }
        }
        else
        {
            context.Response.StatusCode = 400;
            await context.Response.WriteAsync("Nonce header is missing.");
            return;
        }

        await _next(context);
    }
}

Startup.cs 中注册中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<NonceMiddleware>();
    // 其他配置
}
  1. 结合签名
private const string SecretKey = "your_secret_key";

public class SignatureMiddleware
{
    private readonly RequestDelegate _next;

    public SignatureMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Headers.TryGetValue("Signature", out var signatureHeader) &&
            context.Request.Headers.TryGetValue("Data", out var dataHeader) &&
            context.Request.Headers.TryGetValue("Timestamp", out var timestampHeader))
        {
            var expectedSignature = ComputeHMACSHA256(dataHeader + timestampHeader, SecretKey);
            if (!signatureHeader.Equals(expectedSignature))
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Invalid signature, possible replay or tampered request.");
                return;
            }
        }
        else
        {
            context.Response.StatusCode = 400;
            await context.Response.WriteAsync("Signature, data or timestamp header is missing.");
            return;
        }

        await _next(context);
    }

    private string ComputeHMACSHA256(string data, string key)
    {
        using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
        {
            byte[] bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
            return BitConverter.ToString(bytes).Replace("-", "").ToLowerInvariant();
        }
    }
}

Startup.cs 中注册中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<SignatureMiddleware>();
    // 其他配置
}

重放攻击对数据安全的威胁

  1. 数据泄露:攻击者重放包含敏感信息(如登录凭证、交易信息等)的请求,获取用户数据或未授权访问系统资源。
  2. 数据篡改:重放修改后的请求,导致数据被错误修改,影响业务逻辑的正常执行,例如重复转账操作等。
  3. 身份伪造:通过重放身份验证请求,攻击者可以冒充合法用户身份,绕过身份验证机制,执行各种操作,破坏系统安全和数据完整性。