잘못된 서명을 제공하는 PDFBox 다중 서명 Java
몇 가지 pdf 다중 서명 워크 플로 요구 사항이 있습니다. 이 pdf에서는 문서를 변경하지 않고 여러 번 서명되며 2 명 이상이 동일한 문서에 서명 할 수 있습니다. pdf에 서명을 두 번 추가하려고하지만 pdf에 두 번째 서명 한 후 첫 번째 서명이 무효화됩니다. PDF 서명 생성을 위해 PDFBox Java API를 사용했습니다.
PDF 생성 단계 :
- 빈 서명 필드 이름을 추가하여 PDF 생성 : 원본 hello.pdf 출력 파일 이름 hello_tag.pdf 실행 프로그램> TagPDFSignatureFields.java를 사용하여 [email protected] 및 [email protected]
- hello_tag.pdf 파일에서 서명 필드 [email protected]을 가져 와서 처음 서명하면 파일 이름은 hello_signed.pdf 실행 프로그램> SignAndIdentifySignatureFields.java입니다.
- hello_signed.pdf 파일에서 서명 필드 [email protected]을 가져 와서 두 번째 서명하면 파일 이름은 hello_singed2.pdf 실행 프로그램> Sign2.java입니다.
2 단계에서 pdf는 올바르게 서명되지만 3 단계 이후에는 2 단계 서명 된 버전이 무효화되고 3 단계 서명은 acrobat 리더에서 정상으로 표시됩니다.
참조를 위해 링크 Java 소스 코드 및 pdf 샘플을 찾으십시오. Google 드라이브 링크 pdf_multi_signs_pdfbox_java
어떤 도움을 주시면 감사하겠습니다.
답변
요컨대 코드에 많은 문제가 있습니다. 두 번째 서명을 추가 한 후 Adobe Reader가 첫 번째 서명을 유효하지 않은 것으로 표시하는 문제는 실제로 TagPDFSignatureFields
는 잘못된 중복 페이지 트리 항목을 만드는 준비 단계 에 있습니다. Adobe Reader가 현재 불평하지 않더라도 다른 문제도 수정해야합니다.
세부적인 문제 ...
중복 페이지 항목
에 TagPDFSignatureFields
당신의 방법을 addEmptySignField
다음과 같이 시작합니다 :
private void addEmptySignField(String[] args) throws Exception, IOException {
// Create a new document with an empty page.
try (PDDocument document = PDDocument.load(new File(args[0]));)
{
PDPage page = document.getPage(0);
document.addPage(page);
여기에서의 첫 페이지를 검색 document
하고 즉시 해당 페이지를 document
다시 추가 합니다. 이렇게하면 파일의 페이지 루트 트리 노드 hello_tag.pdf
가 다음과 같이 표시됩니다.
2 0 obj
<<
/Type /Pages
/Count 2
/Kids [6 0 R 6 0 R]
>>
endobj
즉, 페이지 트리에는 Adobe Reader가 허용하지 않지만 내부에서 복구하는 동일한 페이지 개체가 두 번 포함됩니다. 서명 된 문서의 경우 Adobe Reader는 이에 대해 막연하게 경고합니다.

그리고 현재 버전 (예 : 2020.013.20066)에서 두 번 서명 된 파일의 Adobe Reader는 첫 번째 서명도 깨진 것으로 표시합니다. 이전 버전 (예 : 2019.012.20040)에서는 그렇게하지 않았습니다. 아마도 이것은 Shadow Attacks가 게시 된 후 유효성 검사 코드가 강화 된 결과 일 것입니다.
참고 : 서명 된 문서 (양식 채우기, 다시 서명, ...)를 조작하면 이전 서명이 깨지는 상황이 발생하면 항상 원본 문서에 이미 문제가 있는지 확인하십시오. 서명 된 문서에 적용된 변경 사항이 허용되는지 확인하는 것은 오류에 매우 민감합니다. 그렇지 않으면 내부에서 수정되어 보이지 않습니다.
잘못된 부분 필드 이름
이메일 주소를 필드 이름으로 사용 [email protected]
하고 [email protected]
예제의 경우 :
signatureField.setPartialName("[email protected]");
...
signatureField1.setPartialName("[email protected]");
( TagPDFSignatureFields
방법 addEmptySignField
)
이러한 부분 필드 이름은 유효하지 않습니다. 부분 필드 이름에는 마침표 ( '.')가 포함되지 않아야합니다.
향후 버전의 PDFBox는이를 방지하기 위해 노력할 것 입니다. PDFBOX-5028을 참조하십시오 .
서명시 기본 리소스 및 기본 모양 설정
서명하는 동안 AcroForm 사전 의 기본 리소스 및 기본 모양을 설정합니다 .
acroForm.setDefaultResources(resources);
...
acroForm.setDefaultAppearance(defaultAppearanceString);
( SignAndIdentifySignatureFields
및 Sign2
방법 addEmptySignField
)
그 자체로는 나쁜 것은 아니지만, 이미 그러한 항목이있는 이전에 서명 된 파일에 대해이 작업을 수행하고 이전과 다른 값으로 설정하면 이전 서명이 무효화 될 수 있습니다 . 여기에 답변 된 문제를 참조 하십시오 .
필요없이 PDF 버전 설정
문서의 청구 된 PDF 버전을 변경하려고합니다.
document.setVersion(1.0f);
( SignAndIdentifySignatureFields
방법 addEmptySignField
)
document.setVersion(2.0f);
( Sign2
방법 addEmptySignField
)
문서 자체에 이미 1.5 이상의 버전이 필요하므로 첫 번째 명령은 무시되지만 두 번째 명령은 실제로 문서 PDF 버전을 2.0으로 설정하여 이전 뷰어에서 문제를 일으킬 수 있습니다.
...
더 많은 문제가있을 가능성이 높습니다. 나는 이미 유일한 첫 번째 페이지 항목 인 중복 페이지 항목을 수정하여 첫 번째 서명을 치료하기에 충분하다는 것을 인식하기 전에 이러한 문제를 처음 발견했을뿐입니다.