【发布时间】:2020-07-21 15:05:06
【问题描述】:
签名修改问题。
我正在使用 DSC 令牌(外部签名)传递文档哈希和签名哈希。
我收到如下错误:“文档自签署以来已被更改或损坏” 获取文档的哈希:-
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();
【问题讨论】:
-
请分享一个示例 PDF 以供分析。此外,您可能必须提供更多代码,您提供的代码看起来非常不完整。
-
@mkl 文件和初始哈希生成代码也上传了,请检查。