【问题标题】:What is wrong with GoDaddy's timestamp server and iTextSharp?GoDaddy 的时间戳服务器和 iTextSharp 有什么问题?
【发布时间】:2015-04-27 07:54:41
【问题描述】:

我正在使用 iTextSharp 库签署 PDF 文档。

当我使用标准 TSAClientBouncyCastle 类从 GoDaddy 的服务器 (http://tsa.starfieldtech.com) 获取时间戳时,响应是一个空流。

同时,它与其他符合 RFC 3161 的时间戳服务器完美配合。此外,当我使用 Microsoft 的 signtool.exe 使用 /tr 选项对 exe 文件进行签名时,它适用于 Godaddy 的服务器。

所以我想知道我尝试使用 iTextSharp 库以编程方式获取时间戳有什么问题。

更新

我使用过这个示例:

http://sourceforge.net/p/itextsharp/code/HEAD/tree/tutorial/signatures/chapter2/C2_01_SignHelloWorld/C2_01_SignHelloWorld.cs

只做了修改,我指定了一个 TSAClient 和一个带有 URL 的构造函数。

这意味着不是调用:

MakeSignature.SignDetached(appearance, pks, chain, null, null, null, 0, subfilter);

我用:

ITSAClient tsaClient = new TSAClientBouncyCastle("http://tsa.starfieldtech.com/");

MakeSignature.SignDetached(外观, pks, 链, null, null, tsaClient, 0, subfilter);

【问题讨论】:

  • 我刚刚使用 TSA 测试了带有时间戳的 iText 签名,它运行良好。因此,您的问题超出了您尚未告诉我们的范围。
  • 您使用哪个 iTextSharp 版本?我明天去办公室看看。
  • @mkl,我正在使用 iTextSharp 5.5.5.0
  • 关于您的编辑:我使用完整的 URL 作为 TSAClientBouncyCastle 构造函数的参数,但您似乎已经删除了协议部分。
  • @mkl,从记忆中输入时出错。实际上,我完全指定了 URL,包括前导“http://”。

标签: itext


【解决方案1】:

当我使用标准 TSAClientBouncyCastle 类从 GoDaddy 的服务器 (http://tsa.starfieldtech.com) 获取时间戳时,响应是一个空流。

我可以使用 iTextSharp 和 C# 而不是 iText 和 Java 来重现这种行为。

通过检查实际网络流量,时间戳请求对象的构建结果相同,但封装 HTTP 请求中使用的 HTTP 标头存在细微差异。

一一调整TSAClientBouncyCastle.GetTSAResponse中的请求头,User-Agent头被证明是罪魁祸首

  • .Net HttpWebRequest 默认好像没有添加这样的头部但是
  • 默认情况下,Java HttpURLConnection 添加包含 Java 版本作为值的标头,例如“Java/1.8.0_20”。

TSAClientBouncyCastle.GetTSAResponse 中显式添加此类标头后,例如像这样:

/**
 * Get timestamp token - communications layer
 * @return - byte[] - TSA response, raw bytes (RFC 3161 encoded)
 */
protected internal virtual byte[] GetTSAResponse(byte[] requestBytes) {
    HttpWebRequest con = (HttpWebRequest)WebRequest.Create(tsaURL);
    // Additional User-Agent header to make http://tsa.starfieldtech.com happy
    con.UserAgent = "iTextSharp";
    con.ContentLength = requestBytes.Length;
    con.ContentType = "application/timestamp-query";
    con.Method = "POST";

时间戳服务器返回正确的时间戳响应。

由于 User-Agent 标头被指定为推荐但不是必需的,因此重点关注的时间戳服务器的这种行为是非常值得怀疑的。


实际上我必须先解决一个不同的问题:我必须在这里使用 HTTP 代理,并且代理总是会干扰 iTextSharp/C# 时间戳请求(但同样不会干扰 iText/Java 时间戳请求)返回一个

System.Net.WebException : The remote server returned an error: (417) Expectation Failed.
at System.Net.HttpWebRequest.GetResponse()

将 HTTP 协议版本限制为 1.0

    con.ProtocolVersion = Version.Parse("1.0");

解决了这个问题。


(@BrunoLowagie、@PauloSoares:在 iTextSharp 中添加 User-Agent 标头应该不会有什么坏处,但我怀疑通常将 HTTP 限制为 1.0 是个好主意。)

【讨论】:

  • 此外,当服务器返回零长度流作为响应时,在 TSAClientBouncyCastle 类中显式抛出带有适当消息的异常将是有益的。目前,它在代码下方出现一个模糊的 NullReferenceException 崩溃。
  • ;) 好吧,我假设原始程序员在收到来自时间戳服务器的 OK(这里的答案是 200 all-is-well)时并没有想象空内容是可能的。但你是对的,对从外部服务接收到的数据进行一定数量的检查是合适的。
猜你喜欢
  • 2013-07-09
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 2014-12-19
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多