我正在使用swisscom数字签名服务,我们有一个测试帐户。那么服务需要哈希代码pdf文件。我们发送
DIGEST_VALUE = $(openssl dgst -binary -SHA256 $ FILE | openssl enc -base64 -A)
我得到了PKCS#7回复。您可以使用此网站解析我的签名回复https://certlogik.com/decoder/ 签名内容为http://not_need_anymore
我遇到同样的问题(因为我们使用相同的代码)
我的回答是sha256加密了。 好吧,我正在使用带有c#的iText来签署pdf文件。我签名并且我看到一些细节(例如原因,位置等)。
这是创建带有签名字段
的pdf文件的方法public static string GetBytesToSign(string unsignedPdf, string tempPdf, string signatureFieldName)
{
if (File.Exists(tempPdf))
File.Delete(tempPdf);
using (PdfReader reader = new PdfReader(unsignedPdf))
{
using (FileStream os = File.OpenWrite(tempPdf))
{
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(36, 748, 250, 400), 1, signatureFieldName);
//IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
PdfSignature external2 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);//ADBE_PKCS7_SHA1);
//as pdf name I tried also PdfName.ETSI_RFC3161
//(ref => https://github.com/SCS-CBU-CED-IAM/itext-ais/blob/master/src/com/swisscom/ais/itext/PDF.java)
appearance.Reason = "For archive";
appearance.Location = "my loc";
appearance.SignDate = DateTime.Now;
appearance.Contact = "myemail@domain.ch";
appearance.CryptoDictionary = external2;
var level = reader.GetCertificationLevel();
// check: at most one certification per pdf is allowed
if (level != PdfSignatureAppearance.NOT_CERTIFIED)
throw new Exception("Could not apply -certlevel option. At most one certification per pdf is allowed, but source pdf contained already a certification.");
appearance.CertificationLevel = level;
MakeSignature.SignExternalContainer(appearance, external,30000);
byte[] array = SHA256Managed.Create().ComputeHash(appearance.GetRangeStream());
return Convert.ToBase64String(array);
}
}
}
Actualls我不使用此方法返回的内容。因为它已经创建了带有签名字段的临时pdf文件。
之后,我给出了这个pdf文件的哈希码,并获得PKCS#7响应。然后使用以下函数,我将签名添加到pdf(它创建另一个pdf文件)。
public static void EmbedSignature(string tempPdf, string signedPdf,
string signatureFieldName, string signature)
{
byte[] signedBytes = Convert.FromBase64String(signature);
using (PdfReader reader = new PdfReader(tempPdf))
{
using (FileStream os = File.OpenWrite(signedPdf))
{
IExternalSignatureContainer external =
new MyExternalSignatureContainer(signedBytes);
MakeSignature.SignDeferred(reader, signatureFieldName, os, external);
}
}
}
方法中的签名参数,我给p7s文件内容如下
string signatureContent = File.ReadAllText(@"mypath\signed_cert.p7s");
signatureContent = signatureContent
.Replace("-----BEGIN PKCS7-----\n", "")
.Replace("-----END PKCS7-----\n","").Trim();
我错过了什么或做错了什么?
答案 0 :(得分:1)
与签署整个签名文件的常规分离签名相比,PDF中的集成签名会签署(并且只能签名)除签名本身之外的所有空间。
(有关更多背景,请阅读this answer)
因此,当您使用占位符准备PDF以嵌入签名
之后提供此pdf文件的哈希码并获取PKCS#7 responde
你散列太多,因为你的散列包括实际签名的(然后是空的,即填充'0'字符)占位符。方法GetBytesToSign
只返回有符号字节范围的哈希值,即除占位符之外的所有内容:
byte[] array = SHA256Managed.Create().ComputeHash(appearance.GetRangeStream());
您必须获取此值或类似地仅散列除签名占位符之外的所有内容。