签署修改的问题。
Iam使用DSC令牌传递文档哈希和签名哈希(外部签名)。
Iam收到错误,例如:“文档自签名以来已被更改或损坏”获取文档哈希:-
public String genrateDigitalCertificateSign() {
try {
src = new FileInputStream(inputFilePath);
OutputStream dest = new FileOutputStream(new File(RESULT_FOLDER, "Test.pdf"));
pdDocument = PDDocument.load(src);
PDSignature pds = null;
String hashdocument = null;
File imgFile = new File(inputImgPath);
PDAcroForm acroForm = pdDocument.getDocumentCatalog().getAcroForm();
if (acroForm == null) {
pdDocument.getDocumentCatalog().setAcroForm(acroForm = new PDAcroForm(pdDocument));
}
acroForm.setSignaturesExist(true);
acroForm.setAppendOnly(true);
acroForm.getCOSObject().setDirect(true);
pds = new PDSignature();
pds.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
pds.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
pds.setSignDate(Calendar.getInstance());
PDPage pdPage = pdDocument.getPage(0);
PDImageXObject pdImage = PDImageXObject.createFromFileByContent(imgFile, pdDocument);
//visible signature rectangle
rectangle = new PDRectangle(200.00, 200.00,150.00,50.00);
List<PDField> acroFormFields = acroForm.getFields();
PDSignatureField signatureField = new PDSignatureField(acroForm);
acroForm.setSignaturesExist(true);
acroForm.setAppendOnly(true);
acroForm.getCOSObject().setDirect(true);
signatureField.setValue(pds);
acroFormFields.add(signatureField);
pdDocument.addSignature(pds);
//creating visible stamp
createVisualSignatureTemplate(pdDocument, signatureField, pdPage, rectangle, pdImage, signDisplayInfo);
externalSigning = pdDocument.saveIncrementalForExternalSigning(dest);
InputStream dataToSign = externalSigning.getContent();
hashdocument = DigestUtils.sha256Hex(dataToSign); // hash is generated
return hashdocument;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
外部签名代码:-
public byte[] sign(byte[] hash)
throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
PrivateKey privKey = pk;
try {
List<Certificate> certList = new ArrayList<>();
certList.addAll(Arrays.asList(chain));
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate
.getInstance(chain[0].getEncoded());
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privKey);
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build())
.build(sha1Signer, new X509CertificateHolder(cert)));
gen.addCertificates(certs);
CMSProcessableInputStream msg = new CMSProcessableInputStream(new ByteArrayInputStream(hash));
CMSSignedData signedData = gen.generate(msg, false);
return signedData.getEncoded();
} catch (GeneralSecurityException e) {
throw new IOException(e);
} catch (CMSException e) {
throw new IOException(e);
} catch (OperatorCreationException e) {
throw new IOException(e);
}
}
签名附加代码:-
public void signedPDF(byte[] hash)
throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException {
byte[] signedHash = sign(hash);
externalSigning.setSignature(signedHash);
IOUtils.closeQuietly(src);
pdDocument.close();
}
此签名附加后,但在打开签名的PDF时会出现如下图所示的错误。
PDF文件链接:https://drive.google.com/file/d/1qRT2CVgET8Ds1fu0b5psii3j8ytPKaLH/view?usp=sharing
[编辑]
public byte[] genrateDigitalCertificateSign() {
try {
src = new FileInputStream(inputFilePath);
OutputStream dest = new FileOutputStream(new File(RESULT_FOLDER, "Test.pdf"));
pdDocument = PDDocument.load(src);
PDSignature pds = null;
String hashdocument = null;
File imgFile = new File(inputImgPath);
PDAcroForm acroForm = pdDocument.getDocumentCatalog().getAcroForm();
if (acroForm == null) {
pdDocument.getDocumentCatalog().setAcroForm(acroForm = new PDAcroForm(pdDocument));
}
acroForm.setSignaturesExist(true);
acroForm.setAppendOnly(true);
acroForm.getCOSObject().setDirect(true);
pds = new PDSignature();
pds.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
pds.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
pds.setSignDate(Calendar.getInstance());
PDPage pdPage = pdDocument.getPage(0);
PDImageXObject pdImage = PDImageXObject.createFromFileByContent(imgFile, pdDocument);
//visible signature rectangle
rectangle = new PDRectangle(200.00, 200.00,150.00,50.00);
List<PDField> acroFormFields = acroForm.getFields();
PDSignatureField signatureField = new PDSignatureField(acroForm);
acroForm.setSignaturesExist(true);
acroForm.setAppendOnly(true);
acroForm.getCOSObject().setDirect(true);
signatureField.setValue(pds);
acroFormFields.add(signatureField);
pdDocument.addSignature(pds);
//creating visible stamp
createVisualSignatureTemplate(pdDocument, signatureField, pdPage, rectangle, pdImage, signDisplayInfo);
externalSigning = pdDocument.saveIncrementalForExternalSigning(dest);
InputStream dataToSign = externalSigning.getContent();
hashdocument = DigestUtils.sha256(dataToSign); // hash is generated
return hashdocument;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
最近签署的PDF文件链接:-https://drive.google.com/file/d/1mZ8Wqppx3EylI1aLYB9Fl8NzibBXZxzR/view?usp=sharing
[编辑2]这是我根据您的建议尝试的流程<在这篇文章中,你指出的第一个问题是什么?我想不出来,请帮忙。
externalSigning = pdDocument.saveIncrementalForExternalSigning(dest);
InputStream dataToSign = externalSigning.getContent();
hashdocument = DigestUtils.sha256(dataToSign); // hash is generated
byte[] signedhash = sign(hashdocument);
externalSigning.setSignature(signedhash);
pdDocument.close();
好的,代码中有两个问题:
您的代码创建了一个签名,该签名包含文档数据哈希的哈希,其中只需要文档数据的哈希。
您的代码主要来自PDFBox示例。如果是外部签名,则检索要签名的内容并将其转发到签名方法:
byte[] cmsSignature = sign(externalSigning.getContent());
(来自扩展了CreateSignatureBase的CreateSignature)
但是,在代码中,首先对要签名的内容进行哈希运算,然后将该哈希转发给sign方法:
public String genrateDigitalCertificateSign() {
...
InputStream dataToSign = externalSigning.getContent();
hashdocument = DigestUtils.sha256Hex(dataToSign); // hash is generated
return hashdocument;
...
}
byte[] signedHash = sign(hash);
就创建CMS签名容器而言,您的符号
方法使用与PDFBox示例相同的代码。
因此,您的代码过于频繁地对文档数据进行散列。要解决这个问题,你必须
我假设您的意图是计算哈希并将其转发到单独的签名服务,因此您的选择是后者。
您的哈希生成方法genrateDigitalcerateSign
返回的哈希值不是实际的byte[]
,而是十六进制对其进行编码并返回十六进制字符串:
hashdocument = DigestUtils.sha256Hex(dataToSign); // hash is generated
return hashdocument;
不过,您的其他方法希望获取并操作实际的字节[]。
要解决这个问题,你必须
我假设您的目的是以字符串形式传输哈希,因此您可以选择后者。
需要通过使用外部webservice对文档哈希进行签名来签署PDF,该过程必须在2个步骤中完成,并使用临时空签名。 在Priyanka问题和Grazina问题之后,阅读了那些帖子上的mkl答案,我现在有一个无效的签名,即使像Grazina那样添加了哈希前缀。 iTextSharp版本:5.5.13.1 这个节目是我上一个问题的另一个问题。当前代码(编译并开始调用SignPDF方法): 获得的结果
首先,虽然我关注StackOverflow已经有相当一段时间了,但这是我第一次发布一些东西,所以如果我做错了或者不按规则做的话,请随时为我指出正确的方向。 我正在开发一个PDF数字签名应用程序,使用iText5,它依赖于一个外部服务,在我准备好PDF签名后提供一个签名哈希。 如iText文档中所述,在第一阶段,我准备了PDF(在最终实现中,所有PDF都可能是多签名的,因此我使用追加模式),如下所示
我已经玩弄了一段时间的iTextSharp 5.5.7,找不到正确的方法从智能卡为PDF制作一个有效的数字签名-Adobe Reader总是说它的签名人和未知,并且不能解码签名的DER数据。 我查看了Makesignature.cs代码以供参考,以及is的功能: 然后,根据iExternalSignature.cs中的“Sign”方法 “@param message要进行散列和签名的邮件” 所以我
Client=My application,Server=MSSP(移动签名服务提供商) 服务器仅对哈希值进行签名。 要签名数据: *Base64编码的SHA-384待签名数据摘要。(64个字符) *Base64编码的SHA-512待签名数据摘要。(88个字符) *要签名的Base64编码的DER编码的PKCS#1摘要信息。 注意:我使用MSSP(移动签名服务提供商)架构。对于SHA256算法,D
第一个选项是不可行的,因为PDF的签名没有时间戳(这是一个非常重要的必要条件),所以选择了第二个选项。 这是我们的代码,首先,我们得到签名外观,并计算散列: 在这一点上,我们有了文档的哈希代码。然后我们将散列发送到webservice,我们得到签名的散列代码。 按照mkl的建议,我遵循了这本书的4.3.3部分PDF文档的数字签名,现在我的代码如下: 第一部分,当我们计算散列时: 在第二部分,我们得
我正在实现一个应用程序,以便在服务器中对PDF文件进行签名,并使用以下场景(使历史变长,变短): 客户端开始签名发送到服务器,日期/时间和水印 服务器将签名字典添加到文件中并发送要签名的数据 客户端签名内容 服务器完成签名 我正在使用PDFBox 2.0.15,并使用新的功能,如下面的代码所示: 在“IF”语句中,我正在生成要签名的数据。在“ELSE”语句中,添加签名,这是通过发布请求(这就是所做