You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用iTextSharp的MakeSignature.SignDetached给PDF加时间戳遇504错误

解决iTextSharp SignDetached添加时间戳时的504网关超时问题

我来帮你分析下这个问题,结合你用Luna HSM、iTextSharp 5.5.11和PkcsInterop.PDF 1.3.0的场景,这个504网关超时大概率和时间戳请求的网络配置、超时设置或者HSM的交互顺序有关,给你几个具体的排查和解决方向:

1. 先确认TSA服务的网络可达性

这个504错误本质是你的程序没法和时间戳服务器(TSA)正常建立连接或获取响应,首先要排除网络层面的问题:

  • 直接用curl或者Postman测试你的TSA地址,发送POST请求(TSA一般要求POST,携带符合RFC 3161格式的请求数据)。如果测试也超时,那问题出在公司网关限制、TSA服务器不可用,或者你用的TSA地址有误。
  • 注意:就算浏览器GET请求TSA地址返回错误,只要能建立连接不超时,就说明网络通路是通的,后续再排查请求格式问题。

2. 自定义TSA客户端,延长超时时间

iTextSharp默认的TSA请求超时时间可能比较短,而HSM签名本身会消耗一定时间,导致后续的TSA请求还没完成就被网关判定为超时。你可以写一个自定义的ITSAClient来设置更长的超时:

public class CustomTsaClient : ITSAClient
{
    private readonly string _tsaUrl;
    private readonly int _timeoutMs;

    public CustomTsaClient(string tsaUrl, int timeoutMs)
    {
        _tsaUrl = tsaUrl;
        _timeoutMs = timeoutMs;
    }

    public int GetTokenSize()
    {
        return 4096; // 根据你的TSA实际情况调整,一般4096足够
    }

    public byte[] GetTimeStampToken(byte[] imprint)
    {
        var request = (HttpWebRequest)WebRequest.Create(_tsaUrl);
        request.Method = "POST";
        request.ContentType = "application/timestamp-query";
        request.Timeout = _timeoutMs; // 设置更长的超时,比如30000ms=30秒

        // 构造符合标准的TSA请求数据
        var tsqGenerator = new TimeStampRequestGenerator();
        tsqGenerator.SetCertReq(true);
        var nonce = new Random().Next();
        var tsRequest = tsqGenerator.Generate(TspAlgorithms.SHA256, imprint, nonce);
        var requestBytes = tsRequest.GetEncoded();

        using (var stream = request.GetRequestStream())
        {
            stream.Write(requestBytes, 0, requestBytes.Length);
        }

        using (var response = (HttpWebResponse)request.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {
                var buffer = new byte[response.ContentLength];
                responseStream.Read(buffer, 0, buffer.Length);
                return buffer;
            }
        }
    }

    public IDigest GetMessageDigest()
    {
        return DigestUtilities.GetDigest("SHA256"); // 和你签名用的哈希算法保持一致
    }
}

然后在签名代码里替换默认的TSA客户端:

// 实例化自定义TSA客户端,设置30秒超时
var customTsa = new CustomTsaClient("你的TSA服务器地址", 30000);
// 调用SignDetached时传入自定义TSA客户端
MakeSignature.SignDetached(appearance, digest, pk, chain, null, null, customTsa, 0, CryptoStandard.CMS);

3. 排查HSM签名与TSA请求的顺序影响

HSM签名操作可能耗时较长,导致后续的TSA请求在网关层面被判定为超时。你可以拆分测试:

  • 先单独测试TSA请求:直接调用上面自定义客户端的GetTimeStampToken方法,传入一个测试哈希值,看是否能正常获取时间戳令牌。如果这一步没问题,说明TSA服务本身是好的,问题出在HSM签名后的请求时机。
  • 检查HSM的签名性能:如果HSM签名耗时超过网关的超时阈值,可能需要优化HSM配置(比如启用签名缓存、使用更高效的算法)。

4. 排除Fiddler代理的干扰

你提到Fiddler返回504,有可能是Fiddler作为代理时无法正确转发TSA的POST请求。可以尝试:

  • 关闭Fiddler后直接运行程序,看是否还会出现超时。
  • 如果必须使用Fiddler,检查Fiddler的代理规则,确保它允许转发TSA地址的POST请求,并且没有设置过短的超时时间。

内容的提问来源于stack exchange,提问作者Deniz Kasar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:44:46