[java] Apache PDFBox를 사용한 PDF 서명 & 인증서 추가

이 포스트에서는 Apache PDFBox라이브러리를 사용하여 PDF 문서에 서명 및 인증서를 추가하는 방법에 대해 알아보겠습니다.

Apache PDFBox란?

Apache PDFBox는 Java로 작성된 오픈 소스 PDF 라이브러리입니다. 이 라이브러리는 PDF 문서의 생성, 조작 및 추출과 같은 다양한 작업을 수행할 수 있습니다.

PDF 문서에 서명을 추가하는 방법에 대해 알아보기 전에 PDFBox를 사용하기 위해 라이브러리를 다운로드하고 프로젝트에 추가해야 합니다. Apache PDFBox의 최신 버전은 공식 웹 사이트에서 다운로드할 수 있습니다.

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version>
</dependency>

PDF 문서에 서명 추가하기

PDFBox를 사용하여 PDF 문서에 서명을 추가하는 과정은 다음과 같습니다.

  1. PDF문서 로드하기: PDF 문서를 로드하여 작업을 수행할 수 있게 합니다.
  2. 서명을 삽입할 위치 지정하기: 서명을 추가할 위치를 지정합니다.
  3. 인증서 로드하기: 서명을 할 인증서를 로드합니다.
  4. 서명 생성하기: 서명을 생성하고 생성된 서명을 인증서와 연결합니다.
  5. 서명 적용하기: 생성한 서명을 PDF 문서에 적용합니다.
  6. 결과 저장하기: 수정된 PDF 문서를 저장합니다.

다음은 Apache PDFBox를 사용하여 PDF 문서에 서명을 추가하는 Java 예제 코드입니다.

import java.io.File;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigProperties;

public class PdfSigningExample {

    private static final String KEYSTORE_FILE = "path/to/keystore.p12";
    private static final String KEYSTORE_PASSWORD = "keystore-password";
    private static final String CERT_ALIAS = "certificate-alias";

    public static void main(String[] args) throws Exception {
        // 1. PDF 문서 로드하기
        File pdfFile = new File("path/to/document.pdf");
        PDDocument document = PDDocument.load(pdfFile);

        // 2. 서명을 삽입할 위치 지정하기
        PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
        PDSignatureField signatureField = acroForm.getField("SignatureFieldName");

        // 3. 인증서 로드하기
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        keystore.load(new FileInputStream(KEYSTORE_FILE), KEYSTORE_PASSWORD.toCharArray());
        PrivateKey privateKey = (PrivateKey) keystore.getKey(CERT_ALIAS, KEYSTORE_PASSWORD.toCharArray());
        Certificate[] certificateChain = keystore.getCertificateChain(CERT_ALIAS);

        // 4. 서명 생성하기
        PDSignature signature = new PDSignature();
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
        signature.setSubFilter(PDSignature.SUBFILTER_ETSI_CADES_DETACHED);
        signature.setName("Signer Name");
        signature.setLocation("Signer Location");
        signature.setReason("Reason for Signing");

        // 5. 서명 적용하기
        SignatureOptions signatureOptions = new SignatureOptions();
        signatureOptions.setVisualSignature(createVisibleSignature());
        document.addSignature(signature, signatureOptions);

        // 6. 결과 저장하기
        String signedPdfFilePath = "path/to/signed-document.pdf";
        document.save(new FileOutputStream(signedPdfFilePath));
        document.close();

        System.out.println("PDF 문서에 서명이 추가되었습니다. 경로: " + signedPdfFilePath);
    }

    private static PDVisibleSignDesigner createVisibleSignature() {
        PDVisibleSignDesigner visibleSignDesigner = new PDVisibleSignDesigner();
        visibleSignDesigner.xAxis(100).yAxis(100).width(200).height(100);
        visibleSignDesigner.page(0).visualSignEnabled(true).setPdDocument(document);
        visibleSignDesigner.signerName("Signer Name").signerLocation("Signer Location").signatureReason("Reason for Signing");
        visibleSignDesigner.preferredSize(0).visualSignEnabled(true).setPdDocument(document);

        PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
        signatureProperties.setPdVisibleSignature(visibleSignDesigner);
        // 서명에 대한 별도의 외관 파일이 있는 경우 setLayer4VisibleSignature을 사용합니다.
        return visibleSignDesigner;
    }

}

위의 예제 코드에서는 PDFBox를 사용하여 PDF 문서를 로드한 다음, 서명을 추가할 위치를 지정합니다. 그런 다음, 서명을 할 인증서를 로드하고, 서명을 생성하고, 서명을 PDF 문서에 적용한 뒤, 결과를 저장합니다.

본 예제에서는 서명에 대한 외관을 디자인하기 위해 PDVisibleSignDesigner를 사용합니다. createVisibleSignature 메서드에서 외관의 위치, 크기, 서명자 정보 등을 설정할 수 있습니다.

이제 위의 예제 코드를 사용하여 Apache PDFBox를 이용하여 PDF 문서에 서명과 인증서를 추가할 수 있습니다.

결론

이 포스트에서는 Apache PDFBox를 사용하여 PDF 문서에 서명과 인증서를 추가하는 방법을 설명했습니다. PDFBox는 강력한 라이브러리로써 다양한 PDF 작업에 사용할 수 있으며, 서명 및 인증서 추가와 같은 보안 관련 작업에도 매우 유용합니다. PDF 문서의 보안 요구사항을 충족시키기 위해 Apache PDFBox를 적극적으로 활용해보시기 바랍니다.

참고 자료