PDFBOX锁定签名仍然可以添加具有有效状态的签名
请参阅我有关防止锁定后添加其他批准/签名的问题。在认证签名pdfbox 上添加锁定字典
我已经成功证明了锁定,但是在我尝试签署/添加另一个签名/批准的锁定之后,我的期望是锁定后,如果另一个符号锁定,则该文档已无效。
Rev 1-> Rev 2 - >认证 - >锁 - >然后Rev 4(来吧,仍然有效签名)
我尝试的是:
//Create empty signature field
PDDocument docEx=PDDocument.load(inputFile);
PDAcroForm acroFormField = docEx.getDocumentCatalog().getAcroForm();
acroFormField.getCOSObject().setNeedToBeUpdated(true);
COSObject fields = acroFormField.getCOSObject().getCOSObject(COSName.FIELDS);
if (fields != null)
fields.setNeedToBeUpdated(true);
acroFormField.setSignaturesExist(true);
acroFormField.setAppendOnly(true);
acroFormField.getCOSObject().setDirect(true);
PDPage pageField = docEx.getPage(page);
// Create empty signature field, it will get the name "Signature1"
PDSignatureField signatureField = new PDSignatureField(acroFormField);
PDAnnotationWidget widget = signatureField.getWidgets().get(0);
PDRectangle rectField = new PDRectangle((float)humanRect.getX(), (float)humanRect.getY(), (float)humanRect.getWidth(), (float)humanRect.getHeight());
widget.setRectangle(rectField);
widget.getCOSObject().setNeedToBeUpdated(true);
widget.setPage(pageField);
pageField.getAnnotations().add(widget);
pageField.getCOSObject().setNeedToBeUpdated(true);
acroFormField.getFields().add(signatureField);
setLock(signatureField, acroFormField);
docEx.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);
docEx.saveIncremental(fos);
fos.close();
//Close and replace with created empty field signature
PDDocument doc = PDDocument.load(signedFile);
FileOutputStream fosSeal = new FileOutputStream(signedFile);
PDSignature signatureLock = new PDSignature();
PDSignatureField signatureFieldLoad = (PDSignatureField) doc.getDocumentCatalog().getAcroForm().getField("Signature1");
LogSystem.info("signatureFieldLoad " + signatureFieldLoad.getValueAsString());
LogSystem.info("signaturelock " + signatureLock);
signatureFieldLoad.setValue(signatureLock);
COSBase lock = signatureFieldLoad.getCOSObject().getDictionaryObject(COS_NAME_LOCK);
if (lock instanceof COSDictionary)
{
COSDictionary lockDict = new COSDictionary();
lockDict.setItem(COS_NAME_ACTION, COS_NAME_ALL);
lockDict.setItem(COSName.TYPE, COS_NAME_SIG_FIELD_LOCK);
COSDictionary transformParams = new COSDictionary(lockDict);
transformParams.setItem(COSName.TYPE, COSName.getPDFName("TransformParams"));
transformParams.setItem(COSName.V, COSName.getPDFName("1.2"));
transformParams.setInt(COSName.P, 1);
transformParams.setDirect(true);
transformParams.setNeedToBeUpdated(true);
COSDictionary sigRef = new COSDictionary();
sigRef.setItem(COSName.TYPE, COSName.getPDFName("SigRef"));
sigRef.setItem(COSName.getPDFName("TransformParams"), transformParams);
sigRef.setItem(COSName.getPDFName("TransformMethod"), COSName.getPDFName("FieldMDP"));
sigRef.setItem(COSName.getPDFName("Data"), doc.getDocumentCatalog());
sigRef.setDirect(true);
COSArray referenceArray = new COSArray();
referenceArray.add(sigRef);
signatureLock.getCOSObject().setItem(COSName.getPDFName("Reference"), referenceArray);
LogSystem.info("LOCK DICTIONARY");
final Predicate<PDField> shallBeLocked;
final COSArray fieldsLock = lockDict.getCOSArray(COSName.FIELDS);
final List<String> fieldNames = fieldsLock == null ? Collections.emptyList() :
fieldsLock.toList().stream().filter(c -> (c instanceof COSString)).map(s -> ((COSString)s).getString()).collect(Collectors.toList());
final COSName action = lockDict.getCOSName(COSName.getPDFName("Action"));
if (action.equals(COSName.getPDFName("Include"))) {
shallBeLocked = f -> fieldNames.contains(f.getFullyQualifiedName());
} else if (action.equals(COSName.getPDFName("Exclude"))) {
shallBeLocked = f -> !fieldNames.contains(f.getFullyQualifiedName());
} else if (action.equals(COSName.getPDFName("All"))) {
shallBeLocked = f -> true;
} else { // unknown action, lock nothing
shallBeLocked = f -> false;
}
lockFields(doc.getDocumentCatalog().getAcroForm().getFields(), shallBeLocked);
setMDPPermission(doc, signatureLock, 2);
// default filter
signatureLock.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
// subfilter for basic and PAdES Part 2 signatures
signatureLock.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signatureLock.setName(name);
// the signing date, needed for valid signature
signatureLock.setSignDate(getDate());
// do not set SignatureInterface instance, if external signing used
SignatureInterface signatureInterface = isExternalSigning() ? null : this;
doc.addSignature(signatureLock, signatureInterface, signatureOptions);
doc.getDocumentCatalog().getAcroForm().getField("Signature1").setPartialName(SignatureField);
if (isExternalSigning()) {
this.tsaUrl=tsaUrl;
ExternalSigningSupport externalSigning = doc.saveIncrementalForExternalSigning(fosSeal);
// invoke external signature serviceUsing fallback
byte[] cmsSignature =IOUtils.toByteArray(externalSigning.getContent());
String sgn=null;
try {
sgn = signingProcess(cmsSignature);
}catch(Exception e)
{
LogSystem.error(e.toString());
e.printStackTrace();
doc.close();
Telegram tele = new Telegram();
tele.Send(e.toString());
return false;
}
// set signature bytes received from the service
if (sgn != null)
{
externalSigning.setSignature(attachSignature(sgn));
}
}
有什么建议吗?还是任何人都可以告诉我,如果我想防止文件更改,它是如何工作的?谢谢
refer my question about prevent adding another approval/signing after lock Add lock Dictionary on Certify Signature PDFBox
i have succeed to certify then lock, but after lock when i try to signing/adding another signature/approval is still valid, what i expected is after lock if another sign the document becomes invalid
rev 1 -> rev 2 -> certified -> lock -> then rev 4 (come and still valid signature)
this what i'm try:
//Create empty signature field
PDDocument docEx=PDDocument.load(inputFile);
PDAcroForm acroFormField = docEx.getDocumentCatalog().getAcroForm();
acroFormField.getCOSObject().setNeedToBeUpdated(true);
COSObject fields = acroFormField.getCOSObject().getCOSObject(COSName.FIELDS);
if (fields != null)
fields.setNeedToBeUpdated(true);
acroFormField.setSignaturesExist(true);
acroFormField.setAppendOnly(true);
acroFormField.getCOSObject().setDirect(true);
PDPage pageField = docEx.getPage(page);
// Create empty signature field, it will get the name "Signature1"
PDSignatureField signatureField = new PDSignatureField(acroFormField);
PDAnnotationWidget widget = signatureField.getWidgets().get(0);
PDRectangle rectField = new PDRectangle((float)humanRect.getX(), (float)humanRect.getY(), (float)humanRect.getWidth(), (float)humanRect.getHeight());
widget.setRectangle(rectField);
widget.getCOSObject().setNeedToBeUpdated(true);
widget.setPage(pageField);
pageField.getAnnotations().add(widget);
pageField.getCOSObject().setNeedToBeUpdated(true);
acroFormField.getFields().add(signatureField);
setLock(signatureField, acroFormField);
docEx.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);
docEx.saveIncremental(fos);
fos.close();
//Close and replace with created empty field signature
PDDocument doc = PDDocument.load(signedFile);
FileOutputStream fosSeal = new FileOutputStream(signedFile);
PDSignature signatureLock = new PDSignature();
PDSignatureField signatureFieldLoad = (PDSignatureField) doc.getDocumentCatalog().getAcroForm().getField("Signature1");
LogSystem.info("signatureFieldLoad " + signatureFieldLoad.getValueAsString());
LogSystem.info("signaturelock " + signatureLock);
signatureFieldLoad.setValue(signatureLock);
COSBase lock = signatureFieldLoad.getCOSObject().getDictionaryObject(COS_NAME_LOCK);
if (lock instanceof COSDictionary)
{
COSDictionary lockDict = new COSDictionary();
lockDict.setItem(COS_NAME_ACTION, COS_NAME_ALL);
lockDict.setItem(COSName.TYPE, COS_NAME_SIG_FIELD_LOCK);
COSDictionary transformParams = new COSDictionary(lockDict);
transformParams.setItem(COSName.TYPE, COSName.getPDFName("TransformParams"));
transformParams.setItem(COSName.V, COSName.getPDFName("1.2"));
transformParams.setInt(COSName.P, 1);
transformParams.setDirect(true);
transformParams.setNeedToBeUpdated(true);
COSDictionary sigRef = new COSDictionary();
sigRef.setItem(COSName.TYPE, COSName.getPDFName("SigRef"));
sigRef.setItem(COSName.getPDFName("TransformParams"), transformParams);
sigRef.setItem(COSName.getPDFName("TransformMethod"), COSName.getPDFName("FieldMDP"));
sigRef.setItem(COSName.getPDFName("Data"), doc.getDocumentCatalog());
sigRef.setDirect(true);
COSArray referenceArray = new COSArray();
referenceArray.add(sigRef);
signatureLock.getCOSObject().setItem(COSName.getPDFName("Reference"), referenceArray);
LogSystem.info("LOCK DICTIONARY");
final Predicate<PDField> shallBeLocked;
final COSArray fieldsLock = lockDict.getCOSArray(COSName.FIELDS);
final List<String> fieldNames = fieldsLock == null ? Collections.emptyList() :
fieldsLock.toList().stream().filter(c -> (c instanceof COSString)).map(s -> ((COSString)s).getString()).collect(Collectors.toList());
final COSName action = lockDict.getCOSName(COSName.getPDFName("Action"));
if (action.equals(COSName.getPDFName("Include"))) {
shallBeLocked = f -> fieldNames.contains(f.getFullyQualifiedName());
} else if (action.equals(COSName.getPDFName("Exclude"))) {
shallBeLocked = f -> !fieldNames.contains(f.getFullyQualifiedName());
} else if (action.equals(COSName.getPDFName("All"))) {
shallBeLocked = f -> true;
} else { // unknown action, lock nothing
shallBeLocked = f -> false;
}
lockFields(doc.getDocumentCatalog().getAcroForm().getFields(), shallBeLocked);
setMDPPermission(doc, signatureLock, 2);
// default filter
signatureLock.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
// subfilter for basic and PAdES Part 2 signatures
signatureLock.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signatureLock.setName(name);
// the signing date, needed for valid signature
signatureLock.setSignDate(getDate());
// do not set SignatureInterface instance, if external signing used
SignatureInterface signatureInterface = isExternalSigning() ? null : this;
doc.addSignature(signatureLock, signatureInterface, signatureOptions);
doc.getDocumentCatalog().getAcroForm().getField("Signature1").setPartialName(SignatureField);
if (isExternalSigning()) {
this.tsaUrl=tsaUrl;
ExternalSigningSupport externalSigning = doc.saveIncrementalForExternalSigning(fosSeal);
// invoke external signature serviceUsing fallback
byte[] cmsSignature =IOUtils.toByteArray(externalSigning.getContent());
String sgn=null;
try {
sgn = signingProcess(cmsSignature);
}catch(Exception e)
{
LogSystem.error(e.toString());
e.printStackTrace();
doc.close();
Telegram tele = new Telegram();
tele.Send(e.toString());
return false;
}
// set signature bytes received from the service
if (sgn != null)
{
externalSigning.setSignature(attachSignature(sgn));
}
}
any suggest ? or anyone can tell me how it work if i want to prevent the document changes ? thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论