GoDaddy 的时间戳服务器和 iTextSharp 有什么问题?
What is wrong with GoDaddy's timestamp server and iTextSharp?
我正在使用 iTextSharp 库来签署 PDF 文档。
当我使用标准 TSAClientBouncyCastle
class 从 GoDaddy 的服务器 (http://tsa.starfieldtech.com) 获取时间戳时,响应是一个空流。
同时,它与其他符合 RFC 3161 标准的时间戳服务器完美配合。此外,当我使用 Microsoft 的 signtool.exe 以 /tr
选项签署 exe 文件时,它可以与 Godaddy 的服务器一起使用。
所以我想知道我尝试使用 iTextSharp 库以编程方式获取时间戳有什么问题。
更新
我用过这个样本:
我只修改了 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);
When I use the standard TSAClientBouncyCastle
class to get time stamp from GoDaddy's server (http://tsa.starfieldtech.com), the response is an empty stream.
我可以使用 iTextSharp 和 C# 重现此行为,但不能使用 iText 和 Java。
通过检查实际的网络流量,时间戳请求 objects 结果是相同构建的,但在封装 HTTP 请求中使用的 HTTP headers 存在细微差别。
正在 TSAClientBouncyCastle.GetTSAResponse
中 header 一个一个地调整请求, User-Agent header被证明是罪魁祸首:
- .Net
HttpWebRequest
默认好像没有加这样一个header但是
- Java
HttpURLConnection
默认添加这样一个 header 包含 Java 版本作为值,例如"Java/1.8.0_20".
在 TSAClientBouncyCastle.GetTSAResponse
中明确添加这样的 header 之后,例如像这样:
/**
* 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";
时间戳服务器returns 正确的时间戳响应。
由于 User-Agent header 被指定为推荐但不是必需的,因此关注的时间戳服务器的这种行为非常值得怀疑。
实际上我不得不先解决一个不同的问题:我必须在这里使用 HTTP 代理,代理总是干扰 iTextSharp/C# 时间戳请求(但同样不会干扰 iText/Java 时间戳请求)返回 a
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 header 应该没什么坏处,但我怀疑通常将 HTTP 限制为 1.0 是个好主意。)
我正在使用 iTextSharp 库来签署 PDF 文档。
当我使用标准 TSAClientBouncyCastle
class 从 GoDaddy 的服务器 (http://tsa.starfieldtech.com) 获取时间戳时,响应是一个空流。
同时,它与其他符合 RFC 3161 标准的时间戳服务器完美配合。此外,当我使用 Microsoft 的 signtool.exe 以 /tr
选项签署 exe 文件时,它可以与 Godaddy 的服务器一起使用。
所以我想知道我尝试使用 iTextSharp 库以编程方式获取时间戳有什么问题。
更新
我用过这个样本:
我只修改了 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);
When I use the standard
TSAClientBouncyCastle
class to get time stamp from GoDaddy's server (http://tsa.starfieldtech.com), the response is an empty stream.
我可以使用 iTextSharp 和 C# 重现此行为,但不能使用 iText 和 Java。
通过检查实际的网络流量,时间戳请求 objects 结果是相同构建的,但在封装 HTTP 请求中使用的 HTTP headers 存在细微差别。
正在 TSAClientBouncyCastle.GetTSAResponse
中 header 一个一个地调整请求, User-Agent header被证明是罪魁祸首:
- .Net
HttpWebRequest
默认好像没有加这样一个header但是 - Java
HttpURLConnection
默认添加这样一个 header 包含 Java 版本作为值,例如"Java/1.8.0_20".
在 TSAClientBouncyCastle.GetTSAResponse
中明确添加这样的 header 之后,例如像这样:
/**
* 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";
时间戳服务器returns 正确的时间戳响应。
由于 User-Agent header 被指定为推荐但不是必需的,因此关注的时间戳服务器的这种行为非常值得怀疑。
实际上我不得不先解决一个不同的问题:我必须在这里使用 HTTP 代理,代理总是干扰 iTextSharp/C# 时间戳请求(但同样不会干扰 iText/Java 时间戳请求)返回 a
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 header 应该没什么坏处,但我怀疑通常将 HTTP 限制为 1.0 是个好主意。)