Jak podpisać PDF w Javie i dodać znacznik czasu

Kiedy musisz chronić umowę, fakturę lub dowolny krytyczny dokument przed manipulacją, jak podpisać PDF bezpiecznie staje się priorytetem. W tym przewodniku dowiesz się, jak dodać podpis cyfrowy i zaufany znacznik czasu do PDF przy użyciu GroupDocs.Signature for Java. Podejście działa offline, obsługuje pliki do 500 MB i wymaga tylko kilku linii kodu.

Szybkie odpowiedzi

Jak podpisać PDF w Javie?

Wczytaj PDF, skonfiguruj DigitalSignature z swoim certyfikatem, opcjonalnie dołącz znacznik czasu z TSA zgodnego z RFC 3161 i wywołaj sign(). Obiekt Signature zapisuje podpisany plik na dysku, zwracając SignResult, który informuje, czy operacja się powiodła i wymienia ewentualne ostrzeżenia. Ten kompletny przepływ wymaga tylko kilku linii kodu Java i automatycznie obsługuje haszowanie, weryfikację certyfikatu oraz pobieranie znacznika czasu.

Dlaczego podpisy cyfrowe są ważne (i dlaczego potrzebujesz znaczników czasu)

Podpis cyfrowy gwarantuje autentyczność (kto podpisał) i integralność (dokument nie został zmieniony). Dodanie znacznika czasu dowodzi, że podpis istniał w określonym momencie, chroniąc Cię nawet jeśli certyfikat podpisujący wygaśnie lub zostanie odwołany. Razem zapewniają nieodrzucalność — kluczową w procesach prawnych, finansowych i regulacyjnych.

Konfiguracja GroupDocs.Signature dla Java

Metody integracji

Wybierz preferowane narzędzie budowania:

Dla użytkowników Maven
Dodaj zależność do swojego pom.xml:

The following Maven coordinates pull the latest stable release of GroupDocs.Signature for Java.

<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-signature</artifactId>
    <version>23.12</version>
</dependency>

Dla użytkowników Gradle
Dodaj linię do swojego build.gradle:

Gradle pobierze bibliotekę z Maven Central.

implementation 'com.groupdocs:groupdocs-signature:23.12'

Bezpośrednie pobranie (jeśli wolisz)
Przejdź do GroupDocs.Signature for Java releases i pobierz plik JAR. Dodaj go ręcznie do classpath swojego projektu. Zobacz GroupDocs.Signature Documentation po pełną dokumentację API. Najnowszą wersję znajdziesz w Latest Version & Releases.

Wskazówka: Maven lub Gradle automatyzują aktualizacje wersji i zależności tranzytywne, oszczędzając czas przy wydawaniu nowych poprawek bezpieczeństwa.

Uzyskanie licencji

GroupDocs oferuje trzy opcje licencjonowania:

  1. Darmowa wersja próbna – przetestuj wszystkie funkcje bez znaku wodnego. Download Trial Version
  2. Licencja tymczasowa – 30‑dniowy klucz pełnego dostępu do rozwoju.
  3. Licencja komercyjna – gotowa do produkcji, nieograniczone użycie. Buy License

Jeśli masz pytania, społeczność jest aktywna na GroupDocs Forum.

Podstawowa inicjalizacja

Signature jest obiektem najwyższego poziomu w GroupDocs.Signature, który reprezentuje pojedynczy plik PDF w pamięci. Po utworzeniu instancji wszystkie operacje odczytu/zapisu przepływają przez niego.

import com.groupdocs.signature.Signature;

String filePath = "YOUR_DOCUMENT_DIRECTORY/sample.pdf";
final Signature signature = new Signature(filePath);

Jak dodać podpis cyfrowy do PDF w Javie: krok po kroku

Proces jest liniowy: importuj klasy, ustaw ścieżki plików, utwórz obiekt Signature, skonfiguruj DigitalSignature z opcjonalnym znacznikiem czasu, zdefiniuj SignOptions, a następnie podpisz i zapisz.

Krok 1: import wymaganych klas

Poniższe importy dają dostęp do konfiguracji podpisu, pozycjonowania i funkcjonalności znacznika czasu.

import com.groupdocs.signature.Signature;
import com.groupdocs.signature.domain.enums.HorizontalAlignment;
import com.groupdocs.signature.domain.enums.VerticalAlignment;
import com.groupdocs.signature.domain.signatures.PdfDigitalSignature;
import com.groupdocs.signature.domain.structs.TimeStamp;
import com.groupdocs.signature.options.sign.DigitalSignOptions;

Krok 2: określ ścieżki plików

Ustaw ścieżki do wejściowego PDF, certyfikatu (PFX) oraz miejsca wyjściowego. Przechowuj plik certyfikatu w bezpiecznym miejscu; zawiera on Twój klucz prywatny.

String filePath = "YOUR_DOCUMENT_DIRECTORY/sample.pdf";
String certificatePath = "YOUR_DOCUMENT_DIRECTORY/certificate.pfx";
String outputFilePath = "YOUR_OUTPUT_DIRECTORY/digitallySignedTimeStamp.pdf";

Krok 3: zainicjalizuj obiekt Signature

Signature jest punktem wejścia dla wszystkich działań podpisywania. Utworzenie go wczytuje PDF do pamięci i przygotowuje API do dalszych operacji.

final Signature signature = new Signature(filePath);

Krok 4: skonfiguruj właściwości podpisu i znacznik czasu

DigitalSignature jest kryptograficzną pieczęcią, która zostanie osadzona w PDF. Możesz także dołączyć znacznik czasu od zaufanego urzędu.

PdfDigitalSignature pdfDigitalSignature = new PdfDigitalSignature();
pdfDigitalSignature.setContactInfo("Contact Information");
pdfDigitalSignature.setLocation("Location Info");
pdfDigitalSignature.setReason("Signing Reason");

// Configure the TimeStamp with URL, User Id, and Password
TimeStamp timeStamp = new TimeStamp("https://freetsa.org/tsr", "User Id", "Password");
pdfDigitalSignature.setTimeStamp(timeStamp);

Używamy FreeTSA (darmowego urzędu czasu) do demonstracji. W produkcji wybierz komercyjny TSA, aby zapewnić gwarantowaną dostępność i status prawny.

Krok 5: skonfiguruj opcje podpisu cyfrowego

SignOptions łączy certyfikat, wygląd wizualny i ustawienia położenia podpisu cyfrowego.

DigitalSignOptions options = new DigitalSignOptions(certificatePath);
options.setPassword("YourCertificatePassword"); // Certificate password
options.setSignature(pdfDigitalSignature); // Attach the PdfDigitalSignature object

// Specify signature alignment (where it appears on the page)
options.setVerticalAlignment(VerticalAlignment.Bottom);
options.setHorizontalAlignment(HorizontalAlignment.Right);

Krok 6: podpisz i zapisz dokument

SignResult dostarcza wynik operacji podpisywania, w tym status sukcesu i ewentualne ostrzeżenia.

try {
    SignResult signResult = signature.sign(outputFilePath, options);
    System.out.println("Document signed successfully!");
    System.out.println("Output: " + outputFilePath);
} catch (Exception e) {
    throw new RuntimeException("Error during signing process: " + e.getMessage());
}

Typowe pułapki do uniknięcia

1. problemy z certyfikatem

Problem: błędy „Invalid certificate”.
Rozwiązanie: Zweryfikuj hasło przy pomocy keytool -list -v -keystore your.pfx.

keytool -list -v -keystore certificate.pfx -storetype PKCS12

2. przekroczenia czasu oczekiwania usługi znacznika czasu

Problem: przekroczenia czasu sieci przy kontaktowaniu się z TSA.
Rozwiązanie: Przetestuj łączność (curl -I https://freetsa.org/tsr), dodaj logikę ponawiania lub skonfiguruj zapasowy TSA.

new File(outputFilePath).getParentFile().mkdirs();

3. problemy z uprawnieniami do plików

Problem: „Access denied” podczas zapisywania.
Rozwiązanie: Upewnij się, że katalog wyjściowy istnieje i aplikacja ma uprawnienia do zapisu.

keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore certificate.pfx -validity 365

4. problemy pamięci przy dużych PDF

Problem: OutOfMemoryError przy dużych plikach.
Rozwiązanie: Zwiększ przydział pamięci JVM (-Xmx4g) lub przetwarzaj pliki w partiach.

5. nieprawidłowe położenie podpisu

Problem: podpis zachodzi na istniejącą treść.
Rozwiązanie: Najpierw przetestuj ustawienia wyrównania; do precyzyjnego położenia użyj opcji opartych na współrzędnych.

Wskazówki dotyczące zarządzania certyfikatami

Uzyskanie certyfikatu do rozwoju

Wygeneruj własnoręcznie podpisany certyfikat przy użyciu keytool Javy do celów testowych.

   String certPassword = System.getenv("CERT_PASSWORD");

Najlepsze praktyki dotyczące certyfikatów

  1. Nigdy nie koduj na stałe haseł – używaj zmiennych środowiskowych.
  2. Rotuj certyfikaty przed ich wygaśnięciem.
  3. Przechowuj klucze prywatne w bezpiecznym sprzęcie (HSM) dla aplikacji o wysokim poziomie bezpieczeństwa.
  4. Twórz kopie zapasowe certyfikatów w zabezpieczonym miejscu.
  5. Weryfikuj certyfikaty przed podpisywaniem, aby wykryć wygasłe lub odwołane.

Najlepsze praktyki bezpieczeństwa

1. chronić klucze prywatne

Przechowuj certyfikaty poza katalogiem projektu, używaj konfiguracji specyficznych dla środowiska i rozważ HSM-y w wdrożeniach korporacyjnych.

2. weryfikować wejściowe PDF

Sprawdź pod kątem uszkodzeń, istniejących podpisów, limitów rozmiaru i zgodności treści przed podpisaniem.

3. wdrożyć logowanie audytu

Loguj każdą operację podpisywania z znacznikiem czasu, użytkownikiem, nazwą dokumentu i statusem.

try {
    SignResult result = signature.sign(outputFilePath, options);
    logger.info("Document signed: " + filePath + " by " + signerEmail);
} catch (Exception e) {
    logger.error("Signing failed: " + filePath + " - " + e.getMessage());
    // Handle appropriately
}

4. używać zaufanych urzędów czasu

Nigdy nie polegaj na lokalnym czasie systemowym; zawsze żądaj znacznika czasu od TSA zgodnego z RFC 3161.

5. wdrożyć obsługę błędów

Przechwytuj wyjątki nie ujawniając wrażliwych szczegółów.

try {
    signature.sign(outputFilePath, options);
} catch (Exception e) {
    // Log detailed error internally
    logger.error("Signing error: " + e.getMessage(), e);
    // Return generic error to client
    throw new ApplicationException("Unable to sign document. Please try again.");
}

Praktyczne przypadki użycia i zastosowania

  1. Systemy zarządzania umowami – pracownicy podpisują NDA i umowy elektronicznie; znaczniki czasu dowodzą dokładnego momentu akceptacji każdej umowy.
  2. Przetwarzanie dokumentów finansowych – masowo podpisuj faktury i zamówienia, zapewniając niezmienny ślad audytu dla regulatorów.
  3. Weryfikacja kwalifikacji edukacyjnych – uczelnie wydają niezmienialne świadectwa, które można natychmiast zweryfikować poprzez link z kodem QR.
  4. Zarządzanie licencjami oprogramowania – generuj certyfikaty licencyjne z podpisem cyfrowym i znacznikiem czasu, aby zapobiec fałszerstwom.
  5. Zgodność regulacyjna (FDA 21 CFR Part 11, itp.) – firmy z branży urządzeń medycznych podpisują SOP i raporty walidacyjne; znaczniki czasu spełniają wymogi nieodrzucalności.

Rozważania dotyczące wydajności i optymalizacji

Zarządzanie pamięcią

Przetwarzaj duże PDF w partiach, szybko zamykaj obiekty Signature i zwiększaj rozmiar sterty w razie potrzeby.

Optymalizacja sieci dla znaczników czasu

Używaj puli połączeń HTTP, wdrażaj ponawianie z wykładniczym opóźnieniem i buforuj znaczniki czasu dla szybkich kolejnych podpisów.

Najlepsze praktyki przetwarzania wsadowego

// Pseudo‑code: process a list of PDFs in parallel, limiting to 5 concurrent TSA calls

Unikaj uruchamiania zbyt wielu wątków; 5‑10 równoczesnych podpisów zapewnia równowagę między przepustowością a obciążeniem TSA.

Optymalizacja operacji dyskowych

Używaj SSD do plików tymczasowych, minimalizuj cykle odczytu/zapisu i usuwaj tymczasowe artefakty po każdym uruchomieniu podpisywania.

Przewodnik rozwiązywania problemów

Błąd: „Invalid certificate password”

Rozwiązanie: Zweryfikuj hasło przy pomocy keytool -list -keystore your.pfx.

ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<SignResult>> futures = new ArrayList<>();

for (String pdfPath : pdfPaths) {
    futures.add(executor.submit(() -> {
        try (Signature sig = new Signature(pdfPath)) {
            return sig.sign(outputPath, options);
        }
    }));
}

// Wait for all to complete
for (Future<SignResult> future : futures) {
    SignResult result = future.get();
    // Process result
}

executor.shutdown();

Błąd: „Timestamp authority not responding”

Rozwiązanie: Przetestuj URL TSA, sprawdź reguły firewalla i dodaj logikę zapasowego TSA.

keytool -list -v -keystore certificate.pfx -storetype PKCS12

Błąd: „PDF is already signed”

Rozwiązanie: Najpierw wykryj istniejące podpisy; dodaj podpis kontraktowy lub podpisz świeżą kopię.

Błąd: „Access denied” przy zapisywaniu

Rozwiązanie: Upewnij się, że katalog wyjściowy istnieje, aplikacja ma prawa zapisu i żaden inny proces nie blokuje pliku.

TimeStamp timeStamp;
try {
    timeStamp = new TimeStamp("https://freetsa.org/tsr", "", "");
} catch (Exception e) {
    // Fallback to alternative TSA
    timeStamp = new TimeStamp("https://alternate-tsa.com/tsr", "", "");
}

Błąd: OutOfMemoryError

Rozwiązanie: Zwiększ przydział pamięci JVM, przetwarzaj PDF w mniejszych partiach lub przejdź na API strumieniowe dla bardzo dużych plików.

Zakończenie i kolejne kroki

Teraz wiesz, jak podpisać pliki PDF w Javie, dodać zaufany znacznik czasu i unikać typowych pułapek. Następnie możesz:

  1. Dodać wiele pól podpisu dla umów wielostronnych.
  2. Weryfikować podpisy programowo przy użyciu GroupDocs.Signature.
  3. Dostosować wygląd wizualny podpisów (obrazy, tekst, pozycjonowanie).
  4. Zbudować solidny serwis masowego podpisywania z kolejkami i monitorowaniem.

Najczęściej zadawane pytania

Q: Jaka jest różnica między podpisem cyfrowym a podpisem elektronicznym?
A: Podpis cyfrowy używa algorytmów kryptograficznych do weryfikacji tożsamości i wykrywania manipulacji, podczas gdy podpis elektroniczny może być tak prosty jak wpisane imię.

Q: Czy potrzebne jest połączenie internetowe do podpisywania PDF?
A: Tylko dla usługi znacznika czasu; sam podpis kryptograficzny odbywa się lokalnie.

Q: Czy podpisane PDF można później edytować?
A: Każda modyfikacja unieważnia podpis, a przeglądarki PDF wyświetlą ostrzeżenie o zmianie dokumentu.

Q: Jak zweryfikować podpisany PDF?
A: Większość czytników PDF weryfikuje automatycznie; programowo użyj API weryfikacji GroupDocs.Signature, aby sprawdzić status, dane podpisującego i ważność znacznika czasu.

Q: Co się stanie, jeśli mój certyfikat wygaśnie po podpisaniu dokumentów?
A: Osadzony znacznik czasu dowodzi, że podpis został utworzony, gdy certyfikat był jeszcze ważny, zachowując moc prawną.

Q: Czy mogę używać tego z przechowywaniem w chmurze (S3, Azure Blob, itp.)?
A: Tak — pobierz PDF do tymczasowej lokalizacji, podpisz go, a następnie prześlij podpisaną wersję z powrotem do chmury.

Q: Czy istnieją limity rozmiaru plików?
A: Biblioteka obsługuje PDF do 500 MB bez wczytywania całego pliku do pamięci; większe pliki mogą wymagać strumieniowania.

Q: Ile kosztuje GroupDocs.Signature w zastosowaniach komercyjnych?
A: Ceny różnią się w zależności od typu wdrożenia; skontaktuj się z działem sprzedaży GroupDocs po najnowsze stawki. Dostępne są darmowe wersje próbne i licencje tymczasowe do oceny.

Q: Czy to działa na serwerach Linux?
A: Zdecydowanie. GroupDocs.Signature for Java jest niezależny od platformy i działa na każdym systemie operacyjnym z JRE.


Ostatnia aktualizacja: 2026-09-05
Testowano z: GroupDocs.Signature 23.9 for Java
Autor: GroupDocs

Powiązane samouczki

File outputFile = new File(outputFilePath);
outputFile.getParentFile().mkdirs(); // Create directories if needed

if (!outputFile.canWrite() && outputFile.exists()) {
    throw new IOException("Cannot write to " + outputFilePath);
}