잘못된 서명을 제공하는 PDFBox 다중 서명 Java

Nov 26 2020

몇 가지 pdf 다중 서명 워크 플로 요구 사항이 있습니다. 이 pdf에서는 문서를 변경하지 않고 여러 번 서명되며 2 명 이상이 동일한 문서에 서명 할 수 있습니다. pdf에 서명을 두 번 추가하려고하지만 pdf에 두 번째 서명 한 후 첫 번째 서명이 무효화됩니다. PDF 서명 생성을 위해 PDFBox Java API를 사용했습니다.

PDF 생성 단계 :

  1. 빈 서명 필드 이름을 추가하여 PDF 생성 : 원본 hello.pdf 출력 파일 이름 hello_tag.pdf 실행 프로그램> TagPDFSignatureFields.java를 사용하여 [email protected][email protected]
  2. hello_tag.pdf 파일에서 서명 필드 [email protected]을 가져 와서 처음 서명하면 파일 이름은 hello_signed.pdf 실행 프로그램> SignAndIdentifySignatureFields.java입니다.
  3. hello_signed.pdf 파일에서 서명 필드 [email protected]을 가져 와서 두 번째 서명하면 파일 이름은 hello_singed2.pdf 실행 프로그램> Sign2.java입니다.

2 단계에서 pdf는 올바르게 서명되지만 3 단계 이후에는 2 단계 서명 된 버전이 무효화되고 3 단계 서명은 acrobat 리더에서 정상으로 표시됩니다.

참조를 위해 링크 Java 소스 코드 및 pdf 샘플을 찾으십시오. Google 드라이브 링크 pdf_multi_signs_pdfbox_java

어떤 도움을 주시면 감사하겠습니다.

답변

3 mkl Nov 27 2020 at 01:26

요컨대 코드에 많은 문제가 있습니다. 두 번째 서명을 추가 한 후 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);

( SignAndIdentifySignatureFieldsSign2방법 addEmptySignField)

그 자체로는 나쁜 것은 아니지만, 이미 그러한 항목이있는 이전에 서명 된 파일에 대해이 작업을 수행하고 이전과 다른 값으로 설정하면 이전 서명이 무효화 될 수 있습니다 . 여기에 답변 된 문제를 참조 하십시오 .

필요없이 PDF 버전 설정

문서의 청구 된 PDF 버전을 변경하려고합니다.

document.setVersion(1.0f);

( SignAndIdentifySignatureFields방법 addEmptySignField)

document.setVersion(2.0f);

( Sign2방법 addEmptySignField)

문서 자체에 이미 1.5 이상의 버전이 필요하므로 첫 번째 명령은 무시되지만 두 번째 명령은 실제로 문서 PDF 버전을 2.0으로 설정하여 이전 뷰어에서 문제를 일으킬 수 있습니다.

...

더 많은 문제가있을 가능성이 높습니다. 나는 이미 유일한 첫 번째 페이지 항목 인 중복 페이지 항목을 수정하여 첫 번째 서명을 치료하기에 충분하다는 것을 인식하기 전에 이러한 문제를 처음 발견했을뿐입니다.