[java] Apache Tika 와 문서 디지털 서명

Apache Tika는 다양한 형식의 문서를 파싱하고 분석하기 위한 오픈 소스 라이브러리입니다. 이 라이브러리는 여러 형식의 문서에서 텍스트 데이터를 추출하고, 메타데이터를 읽을 수 있으며, 문서 내용을 인식할 수 있습니다. Apache Tika는 다양한 파일 형식을 지원하기 위해 다른 라이브러리나 도구를 사용할 수 있습니다.

문서 디지털 서명은 문서의 무결성과 신원을 보증하기 위해 사용되는 중요한 기술입니다. 서명된 문서는 개인이나 기관의 신뢰성과 문서가 변조되지 않았음을 입증하는 역할을 합니다. Apache Tika를 사용하여 문서를 디지털 서명하기 위해서는 몇 가지 단계를 거쳐야 합니다.

1. 문서를 파싱하기 위한 Apache Tika 설정

먼저 Apache Tika를 사용하여 문서를 파싱하려면 의존성을 추가해야 합니다. Maven을 사용한다면 pom.xml 파일에 다음 의존성을 추가합니다.

<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-core</artifactId>
    <version>1.26</version>
</dependency>

2. 문서 디지털 서명용 인증서 생성

문서를 디지털 서명하기 위해서는 인증서가 필요합니다. 인증서는 공개 키와 개인 키의 쌍으로 구성되며, 디지털 서명에 사용됩니다. 인증서는 보안 기관에서 발급 받을 수 있으며, 자체적으로 생성할 수도 있습니다.

인증서를 생성하기 위해서는 Java의 keytool 명령을 사용할 수 있습니다. 다음 명령을 사용하여 키스토어 파일과 인증서를 생성할 수 있습니다.

keytool -genkeypair -alias mydomain -keyalg RSA -keysize 2048 -keystore mykeystore.jks

위 명령은 RSA 알고리즘과 2048 비트 길이의 키를 사용하여 mykeystore.jks라는 키스토어 파일과 mydomain이라는 별칭의 인증서를 생성합니다.

3. 문서에 디지털 서명 추가하기

Apache Tika를 사용하여 문서에 디지털 서명을 추가하는 예제 코드는 다음과 같습니다.

import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.apache.tika.sax.ContentHandlerDecorator;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCSException;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestHolder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.util.io.pem.PemObjectGenerator;
import org.bouncycastle.util.io.pem.PemWriter;

import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

public class DigitalSignatureExample {

    private static final String KEYSTORE_PATH = "/path/to/mykeystore.jks";
    private static final String KEYSTORE_PASSWORD = "keystore_password";
    private static final String KEY_ALIAS = "mydomain";
    private static final String CERTIFICATE_FILE_PATH = "/path/to/certificate.pem";

    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        // Load keystore
        KeyStore keyStore = KeyStore.getInstance("JKS");
        FileInputStream keyStoreFile = new FileInputStream(KEYSTORE_PATH);
        keyStore.load(keyStoreFile, KEYSTORE_PASSWORD.toCharArray());

        // Load private key
        PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS, KEYSTORE_PASSWORD.toCharArray());

        // Load X.509 certificate
        FileInputStream certificateFile = new FileInputStream(CERTIFICATE_FILE_PATH);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(certificateFile);

        // Create signer
        ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey);

        // Create document parser
        Parser parser = new AutoDetectParser();

        // Load the document
        InputStream documentInput = new FileInputStream("/path/to/document.txt");
        Metadata metadata = new Metadata();
        ContentHandlerDecorator handler = new ContentHandlerDecorator(new BodyContentHandler());

        // Parse the document and extract the content
        parser.parse(documentInput, handler, metadata);

        // Sign the document content
        byte[] content = handler.toString().getBytes();
        byte[] signature = signer.generate(content);

        // Verify the signature
        PublicKey publicKey = certificate.getPublicKey();
        boolean signatureValid = signer.verify(content, signature);

        if (signatureValid) {
            System.out.println("Signature is valid.");
        } else {
            System.out.println("Signature is invalid.");
        }
    }
}

위 예제 코드에서 KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_ALIAS, CERTIFICATE_FILE_PATH 등을 적절히 수정하여 사용하시면 됩니다. 이 코드는 Tika를 사용하여 문서를 파싱하고, 파싱된 내용을 디지털 서명하는 과정을 보여줍니다.

Apache Tika를 사용하여 문서를 디지털 서명하는 방법에 대한 자세한 내용은 Apache Tika 문서를 참조하시기 바랍니다.