كيفية إضافة التوقيعات الرقمية إلى المستندات في جافا

مقدمة

تنفيذ وظيفة add digital signature java قد يشعر وكأنه عبور حقل ألغام. عليك التعامل مع صيغ الشهادات، موضع التوقيع، وسياسات الأمان الصارمة — كل ذلك مع الحفاظ على تجربة مستخدم سلسة. خطوة واحدة خاطئة قد تؤدي إلى توقيعات غير صالحة أو مستندات تفشل في التحقق في Adobe Reader.

لحسن الحظ، لا تحتاج إلى إعادة اختراع العجلة أو التعامل مع التشفير منخفض المستوى. سواء كنت تبني بوابة إدارة عقود، أو عملية دفع إلكترونية تتطلب إيصالات موقعة، أو سير عمل داخلي للموارد البشرية، فإن مكتبة جافا موثوقة توفر لك ساعات من التطوير وتزيل الأخطاء الشائعة.

في هذا الدليل سنستعرض GroupDocs.Signature for Java، مكتبة تجارية تُجرد عنك عبء التوقيعات الرقمية. ستتعلم كيف:

  • إعداد المكتبة وتكوين الشهادات بشكل صحيح
  • توقيع ملفات PDF، Word، Excel، وPowerPoint بطابع بصري احترافي
  • التحقق من التوقيعات ومعالجة الأخطاء الشائعة مثل الشهادات غير الموثوقة أو اختناقات الذاكرة
  • تطبيق إجراءات أمان أفضل للمواقع الإنتاجية

بنهاية الدليل ستحصل على تنفيذ جاهز يمكنك توسيعه لأي نوع مستند يتعامل معه تطبيقك.

إجابات سريعة

  • ما هي المكتبة التي تسمح لك بإضافة توقيعات رقمية في جافا؟ GroupDocs.Signature for Java.
  • كم عدد صيغ المستندات المدعومة؟ أكثر من 30 صيغة، بما في ذلك PDF، DOCX، XLSX، PPTX، وملفات الصور.
  • هل أحتاج إلى رخصة للإنتاج؟ نعم—ترخيص تجاري يزيل العلامات المائية ويفتح جميع الميزات.
  • هل يمكنني توقيع ملفات PDF الكبيرة (100+ صفحة) دون أخطاء OOM؟ نعم—عن طريق ضبط حجم heap للـ JVM واستخدام خيار setAllPages(false).
  • هل يدعم توقيت الطابع الزمني؟ بالطبع؛ يمكنك إرفاق رمز من سلطة توقيت موثوقة (TSA) لضمان الصلاحية طويلة الأمد.

ما هو add digital signature java؟

add digital signature java يشير إلى العملية البرمجية لإدراج توقيع تشفيري داخل مستند رقمي باستخدام واجهات برمجة تطبيقات جافا. يربط التوقيع هوية المُوقّع—المُتحققة عبر شهادة رقمية—بمحتوى المستند، مما يضمن النزاهة، عدم الإنكار، والقدرة على التنفيذ القانوني عبر المنصات.

لماذا تنفيذ digital signatures java؟

GroupDocs.Signature يدعم أكثر من 30 صيغة إدخال وإخراج ويمكنه معالجة ملفات تصل إلى 500 ميغابايت دون تحميل الملف بالكامل في الذاكرة، مما يحقق تحسين سرعة 2‑5× مقارنةً بتنفيذات PDFBox اليدوية. هذه الفائدة الكمية تُترجم إلى أوقات معاملات أسرع وتكاليف خادم أقل لأحمال العمل ذات الحجم الكبير.

المتطلبات المسبقة

قبل البدء، تأكد من وجود ما يلي:

  • Java Development Kit (JDK) 8+ – يُفضَّل JDK 11 لدعمه المحسن لـ TLS.
  • IDE – IntelliJ IDEA، Eclipse، أو VS Code مع ملحقات جافا.
  • GroupDocs.Signature for Java – سنوضح ثلاث طرق لإضافتها إلى مشروعك.
  • شهادة رقمية صالحة بصيغة PFX أو P12 (تحتاج إلى المفتاح الخاص وكلمة المرور).

اختياري لكن مفيد:

  • إلمام بـ Maven أو Gradle لإدارة التبعيات.
  • ملف PDF أو DOCX أو XLSX تجريبي لاختبار تدفق التوقيع.

كيف أقوم بتثبيت GroupDocs.Signature for Java؟

GroupDocs.Signature يتطلب إضافة بسيطة إلى تكوين البناء الخاص بك. استخدم المقتطف الذي يتطابق مع أداة البناء التي تستخدمها، استبدل نسخة العنصر بالنسخة المستقرة الأخيرة، ثم نفّذ أمر البناء لجلب المكتبة من Maven Central.

Maven (add to your pom.xml):

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

Gradle (add to your build.gradle):

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

التثبيت اليدوي (إذا لم تستخدم أداة بناء):
حمّل ملف JAR من صفحة الإصدارات الرسمية — GroupDocs.Signature for Java releases — وأضفه إلى مسار الـ classpath الخاص بك.

نصيحة احترافية: دائمًا استخدم أحدث نسخة مستقرة. في وقت كتابة هذا الدليل، النسخة 23.12 هي الحالية، لكن الإصدارات الأحدث غالبًا ما تحتوي على تصحيحات أمان وتحسينات أداء.

كيف أحصل على رخصة GroupDocs وأطبقها؟

GroupDocs.Signature يتطلب رخصة للاستخدام الإنتاجي. الرخصة تزيل العلامات المائية وتفتح مجموعة الميزات الكاملة، مما يضمن أن المستندات الموقعة تتوافق مع سياسات المؤسسة.

بدون رخصة صالحة، ستظهر علامة مائية مرئية على المستندات الموقعة، وهذا مفيد فقط لأغراض التقييم.

كيف أقوم بتهيئة كائن Signature؟

فئة Signature هي نقطة الدخول لجميع عمليات المستند. تمثل ملفًا واحدًا في الذاكرة وتوفر طرقًا للتوقيع، والتحقق، واستخراج التوقيعات. إنشاء نسخة من Signature يحمل الملف الهدف ويجهزه للمعالجة اللاحقة.

Signature signature = new Signature("path/to/input.pdf");

ماذا يحدث هنا؟
السطر ينشئ نسخة من Signature تحمل المستند الهدف. يمكن أن يكون المسار مطلقًا أو نسبيًا؛ فقط تأكد من وجود الملف. يمكن إعادة استخدام هذا الكائن لتوقيع أو تحقق متعدد، مما يقلل الحمل في سيناريوهات الدفعات.

كيف أقوم بتكوين خيارات التوقيع الرقمي؟

خيارات التوقيع الرقمي تضم جميع الإعدادات المطلوبة لإنتاج توقيع PKI صالح، بما في ذلك معلومات الشهادة، المظهر البصري، وقواعد الموضع. التكوين الصحيح يضمن أن التوقيع الناتج يكون قويًا من الناحية التشفيرية ومناسبًا بصريًا لنوع المستند.

كيف أقوم بإعداد تفاصيل الشهادة؟

فئة DigitalSignOptions تحتفظ بجميع إعدادات الشهادة. ما يلي هو التعريف الأولي لهذه الفئة.

DigitalSignOptions يحدد المعلمات التشفيرية—ملف الشهادة، كلمة المرور، والبيانات الوصفية الاختيارية—التي تستخدمها المكتبة لإنشاء توقيع PKI صالح.

DigitalSignOptions options = new DigitalSignOptions();
options.setCertificatePath("YOUR_DOCUMENT_DIRECTORY/certificate.pfx");
options.setCertificatePassword("yourPassword");
options.setReason("Approved Contract");
options.setContact("legal@yourcompany.com");
options.setLocation("New York, USA");

نقاط رئيسية:

  • لا تقم أبدًا بكتابة كلمة المرور صراحةً في الشيفرة؛ حمّلها من متغيرات البيئة أو مدير أسرار.
  • استخدم setReason، setContact، وsetLocation لتزويد المراجعين بسياق عند فحص خصائص التوقيع.

كيف أقوم بتخصيص المظهر البصري للتوقيع؟

SignatureOptions (فئة فرعية من DigitalSignOptions) تتحكم في العرض داخل الصفحة. تتيح لك إرفاق صورة، ضبط الحجم، وتحديد موضع الطابع البصري على الصفحة.

SignatureOptions تتيح لك إرفاق صورة، ضبط الحجم، وتحديد موضع الطابع البصري على الصفحة.

options.setImageFilePath("YOUR_DOCUMENT_DIRECTORY/signature.png");
options.setAllPages(true);
options.setWidth(150);
options.setHeight(0); // Auto‑scale based on image aspect ratio
  • ImageFilePath: ضع مسارًا إلى ملف PNG أو JPG لتوقيعك المكتوب يدويًا أو شعار الشركة. PNG الشفاف هو الأفضل.
  • AllPages: عيّن إلى true للعقود التي تحتاج إلى دليل على كل صفحة؛ وإلا false يوقع فقط الصفحة الأخيرة.
  • Width/Height: يُقاس بالبكسل؛ ارتفاع 50‑80 بكسل يبدو احترافيًا لمعظم مستندات الأعمال.

كيف أقوم بالتحكم في المحاذاة والهوامش؟

إعدادات المحاذاة تحدد مكان وضع الطابع على الصفحة، بينما تُضيف الهوامش مساحة حول العنصر البصري لمنع ملامسته لحواف الصفحة. المحاذاة السليمة تحسن القابلية للقراءة وتضمن عدم تداخل التوقيع مع المحتوى الموجود.

AlignmentOptions توفر ثوابت موضع عمودية وأفقية مثل Bottom، Right، Top، وCenter.

options.setVerticalAlignment(VerticalAlignment.Bottom);
options.setHorizontalAlignment(HorizontalAlignment.Right);
options.setPadding(10);
  • Padding: يضيف مساحة هوامش حول الطابع؛ قيمة 10 بكسل تمنع الصورة من ملامسة حواف الصفحة.
  • مثال واقعي: في قوالب الفواتير قد تستخدم Top/Left لوضع توقيع المُعتمد بالقرب من العنوان.

كيف أقوم بإضافة سطر توقيع لمستندات Office؟

عند توقيع ملفات DOCX أو XLSX، سطر توقيع مرئي يحسن القابلية للقراءة للمستخدم النهائي. المكتبة تنشئ سطر توقيع بنمط Microsoft يُظهر اسم المُوقّع، اللقب، والبريد الإلكتروني، مما يحاكي تجربة Office الأصلية.

SignatureLineOptions تنشئ سطر توقيع بنمط Microsoft يُظهر اسم المُوقّع، اللقب، والبريد الإلكتروني.

options.setSignatureLineText("John Doe", "Chief Legal Officer", "j.doe@yourcompany.com");
  • تُهمل هذه الميزة في ملفات PDF لكنها أساسية لملفات Word وExcel التي تُفتح في Microsoft Office.

كيف أقوم فعليًا بتوقيع مستند؟

حمّل الملف المصدر باستخدام نسخة Signature، طبّق DigitalSignOptions المُكوَّنة بالكامل، واستدعِ sign(). المكتبة تكتب ملفًا جديدًا إلى مسار الإخراج، وتترك الأصلي دون تعديل. للملفات الكبيرة (50+ صفحة) توقع نافذة معالجة تتراوح بين 2‑5 ثوانٍ؛ فكر في التنفيذ غير المتزامن في خدمات الويب.

Signature signature = new Signature("SAMPLE_WORDPROCESSING/contract.docx");
DigitalSignOptions options = new DigitalSignOptions();
// ...configure options as shown earlier...
signature.sign("OUTPUT_FOLDER/signed_contract.docx", options);

ملاحظة أداء: للوثائق التي تزيد عن 100 صفحة، زد حجم heap للـ JVM (-Xmx2g) أو عطل setAllPages(true) لتقليل استهلاك الذاكرة.

كيف أقوم باستكشاف المشكلات الشائعة؟

عند فشل التوقيع، غالبًا ما تكون المشكلات المرتبطة بالتعامل مع الشهادة، الموضع البصري، أو قيود الذاكرة. حدد العَرَض، ثم اتبع قائمة الفحص المستهدفة أدناه لحل المشكلة بسرعة.

لماذا أرى أخطاء “Invalid Certificate” أو “Cannot Load Certificate”؟

هذه الاستثناءات عادةً ما تنبع من أحد أربعة أسباب:

  1. كلمة مرور غير صحيحة – تحقق باستخدام OpenSSL: openssl pkcs12 -info -in yourcert.pfx.
  2. شهادة منتهية – افحص الصلاحية باستخدام keytool -list -v -keystore yourcert.pfx.
  3. صيغة ملف غير صحيحة – تُقبل فقط .pfx أو .p12 (التي تحتوي على المفاتيح الخاصة).
  4. مشكلات أذونات الملف – تأكد من أن عملية جافا يمكنها قراءة ملف الشهادة.

لماذا لا يظهر التوقيع على الصفحة؟

  • قد يكون علم AllPages مضبوطًا على false، لذا تنظر إلى صفحة بدون طابع.
  • قد يكون مسار الصورة مكتوبًا بخطأ؛ اطبع options.getImageFilePath() للتأكد.
  • قد تدفع إعدادات المحاذاة الطابع خارج الشاشة؛ جرّب مؤقتًا Center للتصحيح.

لماذا يُظهر Adobe Reader “Signature Invalid”؟

  • الشهادة غير موثوقة – الشهادات الذاتية تولد تحذيرات. استخدم شهادة صادرة عن CA للإنتاج.
  • سلسلة شهادة غير مكتملة – تأكد من أن ملف .pfx يحتوي على الشهادات الوسيطة والجذر.
  • غياب الطابع الزمني – بدون رمز TSA، قد يُعتبر التوقيع غير صالح بعد انتهاء صلاحية الشهادة. GroupDocs يدعم الطابع الزمني عبر setTimeStampOptions().

كيف أتجنب OutOfMemoryError مع ملفات PDF الضخمة؟

  • زد حجم heap للـ JVM (-Xmx4g أو أكثر).
  • وقع فقط الصفحات المطلوبة (setAllPages(false)).
  • عالج الملفات على دفعات أصغر أو استخدم البث إذا كنت في بيئة محدودة الموارد.

كيف أقوم بإدارة الشهادات بأمان في بيئة الإنتاج؟

لا تُدمج الشهادات أو كلمات المرور في الشيفرة المصدرية. اتبع الخطوات التالية:

  1. خزن ملفات .pfx في مخزن آمن (AWS Secrets Manager، Azure Key Vault، أو HashiCorp Vault).
  2. حمّل كلمة المرور في وقت التشغيل من متغيرات البيئة أو واجهة برمجة تطبيقات المخزن.
  3. قيد أذونات نظام الملفات بحيث لا يقرأ حساب الخدمة إلا الشهادة.
  4. جدد الشهادات قبل 30 يومًا على الأقل من انتهاء صلاحيتها وحدث السر المخزن وفقًا لذلك.
String certPath = System.getenv("CERT_PATH");
String certPassword = System.getenv("CERT_PASSWORD");
options.setCertificatePath(certPath);
options.setCertificatePassword(certPassword);

كيف أقوم بتسجيل عمليات التوقيع للامتثال التدقيقي؟

سجلات التدقيق توفر دليلًا على عدم الإنكار. سجِّل الحقول التالية لكل عملية توقيع:

  • اسم المستند والهاش قبل التوقيع
  • هوية المُوقّع (موضوع الشهادة)
  • طابع الوقت للعملية (يفضل UTC)
  • حالة النتيجة (نجاح/فشل) وتفاصيل الخطأ إن وجدت
logger.info("Signing document {} with certificate {} at {}", docPath, options.getCertificatePath(), Instant.now());

كيف أقوم بالتحقق من توقيع بعد تطبيقه؟

التحقق يضمن أن المستند لم يتعرض لأي تعديل بعد التوقيع. استخدم طريقة verify() التي تُعيد كائن VerificationResult يحتوي على حالة الصلاحية، تفاصيل المُوقّع، وأية معلومات طابع زمني. تحقق ناجح يؤكد كلًا من النزاهة والموثوقية.

VerificationResult result = signature.verify("OUTPUT_FOLDER/signed_contract.docx");
if (result.isValid()) {
    logger.info("Signature is valid and trusted.");
} else {
    logger.warn("Signature verification failed: {}", result.getErrorMessage());
}

كيف يمكنني إضافة توقيعات متعددة إلى مستند واحد؟

قد تحتاج إلى توقيع موافق وشاهد. استدعِ sign() عدة مرات مع كائنات DigitalSignOptions متميزة، كل منها مُكوَّن بشهادته وإعداداته البصرية الخاصة. المكتبة تحتفظ بالتوقيعات الموجودة وتضيف الجديدة.

// First signature (approver)
signature.sign("output.docx", approverOptions);
// Second signature (witness)
signature.sign("output.docx", witnessOptions);

كيف أقوم بإنشاء طريقة مصنع لأنواع المستندات المختلفة؟

طريقة مساعدة يمكنها إرجاع DigitalSignOptions مُكوَّنة مسبقًا بناءً على امتداد الملف، مما يحافظ على مبدأ DRY. هذه الطريقة تُركز تحميل الشهادة، الإعدادات البصرية الافتراضية، ومنطق اختيار الصفحات للـ PDF، Word، Excel وغيرها من الصيغ المدعومة.

public DigitalSignOptions getOptionsFor(String extension) {
    DigitalSignOptions opts = new DigitalSignOptions();
    // common settings
    if (extension.equalsIgnoreCase("pdf")) {
        opts.setImageFilePath("signatures/pdf_stamp.png");
    } else if (extension.equalsIgnoreCase("docx")) {
        opts.setSignatureLineText("Jane Smith", "Finance Manager", "j.smith@company.com");
    }
    return opts;
}

كيف أقوم بالتحقق من أن المستند لم يتم توقيعه مسبقًا؟

قبل تطبيق توقيع جديد، تحقق من وجود توقيعات سابقة لتجنب التوقيع المزدوج. استخدم طريقة getSignatures()؛ إذا كانت المجموعة المرجعة غير فارغة، قرّر إما إضافة توقيع جديد أو إلغاء العملية.

List<SignatureInfo> existing = signature.getSignatures();
if (!existing.isEmpty()) {
    logger.warn("Document already contains {} signatures.", existing.size());
}

تطبيقات عملية (حالات استخدام واقعية)

  1. أتمتة سير عمل العقود – عندما يصل العقد إلى حالة “مُعتمد” في نظام BPM الخاص بك، شغّل خدمة التوقيع لإدراج شهادة القسم القانوني وإرسال النسخة الموقعة إلى المورد.
  2. أنظمة موافقة الفواتير – بعد توقيع المالية للفاتورة، أضف توقيعًا رقميًا تلقائيًا قبل إرساله إلى العميل، لتوفير دليل تشفيري على الأصالة.
  3. بوابات التحقق من المستندات – قدّم بوابة ذاتية الخدمة حيث يرفع المستخدم PDF، تقوم أنت بتوقيعه بشهادة الشركة، وتعيد ملفًا غير قابل للتلاعب للامتثال القانوني.
  4. الصناعات ذات المتطلبات الصارمة – في الرعاية الصحية (HIPAA) أو المالية (SOX)، تُلبي التوقيعات الرقمية متطلبات التدقيق بإثبات من وقع المستند ومتى.
  5. توزيع السياسات الداخلية – استبدل الختم اليدوي لسياسات الموارد البشرية بعملية آلية توقّع الـ PDF النهائي بشهادة مدير الموارد البشرية، لضمان استلام كل موظف نسخة مُتحققة.

اعتبارات الأداء

حجم المستندمتوسط زمن المعالجةالإعدادات الموصى بها
1‑5 صفحات~0.5 ثالإعدادات الافتراضية
5‑50 صفحات1‑3 ثزيادة الذاكرة، setAllPages(true) إذا لزم الأمر
50‑200 صفحات3‑10 ثsetAllPages(false)، تنفيذ غير متزامن، زيادة الذاكرة

نصائح التحسين:

  • أعد استخدام نسخة Signature واحدة عند توقيع ملفات متعددة في دفعة.
  • خزن كائن DigitalSignOptions محمَّل؛ تحميل الشهادة مرارًا يضيف عبئًا.
  • في خدمات الويب، غلف استدعاء التوقيع داخل CompletableFuture أو أرسله إلى طابور رسائل للحفاظ على استجابة الواجهة.

نصائح احترافية (استخدام متقدم)

  • الطابع الزمني لصلاحية طويلة الأمد – أرفق رمز TSA باستخدام setTimeStampOptions() لضمان بقاء التوقيعات صالحة بعد انتهاء صلاحية الشهادة.
  • التوقيعات غير المرئية – احذف ImageFilePath واضبط Width/Height إلى 0 لإنشاء توقيع تشفيري صالح لكنه غير مرئي، مفيد للعمليات الخلفية التي لا تحتاج إلى طابع بصري.
  • توقيعات QR‑code مخصصة – يمكن لـ GroupDocs تضمين رمز QR يحتوي على بيانات المُوقّع؛ مثالي للمستندات اللوجستية التي تحتاج إلى تحقق سريع عبر الأجهزة المحمولة.

الأسئلة المتكررة

س: ما الفرق الرئيسي بين GroupDocs.Signature و iText لتوقيع PDF؟
ج: iText يركز فقط على PDF ويتطلب منك التعامل مع التشفير منخفض المستوى بنفسك، بينما GroupDocs.Signature يدعم أكثر من 30 صيغة، يوفر طوابع بصرية جاهزة، ويجرد عنك التعامل مع الشهادات، مما يقلل وقت التطوير بشكل كبير.

س: هل يمكنني دمج GroupDocs.Signature في خدمة microservice مبنية على Spring Boot؟
ج: نعم. أضف تبعية Maven، أنشئ Bean من نوع @Service يلتف حول منطق التوقيع، وحقنه أينما احتجت لتوقيع المستندات. هذا يبقي المتحكمات خفيفة ويجعل كود التوقيع قابلًا لإعادة الاستخدام.

س: ما مدى أمان التوقيعات التي تُنشئها GroupDocs.Signature؟
ج: المكتبة تستخدم خوارزميات PKI القياسية (RSA/ECDSA) وتلتزم بنفس المواصفات التي تتبعها المتصفحات وAdobe Reader. الأمان يعتمد على جودة شهادتك؛ استخدم دائمًا شهادة صادرة عن CA واحمِ المفتاح الخاص.

س: هل ستعمل المستندات الموقعة عبر مختلف قارئات PDF؟
ج: بالتأكيد. طالما أن شهادة التوقيع موثوقة، فإن Adobe Reader، Foxit، والمتصفحات الحديثة ستتحقق من صحة التوقيع بشكل صحيح. الشهادات الذاتية ستظهر تحذيرًا لكنها تظل صالحة تقنيًا.

س: هل يمكن توقيع المستندات دون صورة توقيع مرئية؟
ج: نعم—اكتفِ بحذف ImageFilePath واضبط معلمات الحجم إلى صفر. التوقيع الناتج غير مرئي لكنه لا يزال تشفيريًا صالحًا، مثالي لأتمتة الخلفية حيث لا تُحتاج إشارات بصرية.

الخلاصة

أصبح لديك الآن خارطة طريق كاملة وجاهزة للإنتاج لإضافة add digital signature java باستخدام GroupDocs.Signature. غطينا كل شيء من إعداد البيئة وتعامل الشهادات إلى تخصيص المظهر البصري، تحسين الأداء، والسيناريوهات المتقدمة مثل التوقيعات المتعددة والطابع الزمني.

الخطوات التالية:

  1. اختبر الشيفرة النموذجية باستخدام شهاداتك الخاصة وقوالب المستندات.
  2. عزّز نشرك بنقل الشهادات إلى مدير أسرار وتكوين حدود ذاكرة JVM المناسبة.
  3. وسّع طرق المساعدة لدعم المعالجة الدفعية أو دمجها مع محرك سير العمل الحالي.

للمزيد من التفاصيل، استكشف الوثائق الرسمية ومنتديات المجتمع عبر الروابط أدناه.


آخر تحديث: 2026-06-11
تم الاختبار مع: GroupDocs.Signature 23.12 for Java
المؤلف: GroupDocs

الموارد:

import com.groupdocs.signature.Signature;

public class SignatureSetup {
    public static void main(String[] args) {
        Signature signature = new Signature("path/to/your/document");
        // Your signing logic goes here
    }
}
import com.groupdocs.signature.options.sign.DigitalSignOptions;
import com.groupdocs.signature.domain.enums.HorizontalAlignment;
import com.groupdocs.signature.domain.enums.VerticalAlignment;
import com.groupdocs.signature.exception.GroupDocsSignatureException;

DigitalSignOptions options = new DigitalSignOptions("YOUR_DOCUMENT_DIRECTORY/CertificatePfx");
options.setPassword("1234567890"); // Ensure your certificate password is secure
options.setReason("Sign"); // Reason for signing, e.g., "Contract Approval"
options.setContact("JohnSmith"); // Contact information of the signer
options.setLocation("Office1"); // Location where document is signed
options.setImageFilePath("YOUR_DOCUMENT_DIRECTORY/ImageHandwrite");
options.setAllPages(true); // Apply signature to all pages of the document
options.setWidth(0); // Auto-width based on content
options.setHeight(60); // Height in pixels
options.setVerticalAlignment(VerticalAlignment.Bottom);
options.setHorizontalAlignment(HorizontalAlignment.Right);
Padding padding = new Padding();
padding.setBottom(10); // Bottom padding for aesthetic spacing
padding.setRight(10); // Right padding to prevent clipping at edges
options.setMargin(padding);
import com.groupdocs.signature.domain.signatures.DigitalSignatureAppearance;

options.setAppearance(new DigitalSignatureAppearance("John Smith", "Title", "jonny@test.com"));
try {
    Signature signature = new Signature("YOUR_DOCUMENT_DIRECTORY/SAMPLE_WORDPROCESSING");
    String outputFilePath = "YOUR_OUTPUT_DIRECTORY/DigitalAppearance.docx";
    signature.sign(outputFilePath, options);
} catch (GroupDocsSignatureException e) {
    throw new RuntimeException(e.getMessage());
}
// BAD - Don't do this
options.setPassword("1234567890");

// GOOD - Load from environment variable
String certPassword = System.getenv("CERT_PASSWORD");
if (certPassword == null) {
    throw new RuntimeException("CERT_PASSWORD environment variable not set");
}
options.setPassword(certPassword);
logger.info("Document signed: {}, SignedBy: {}, Timestamp: {}", 
    documentName, signerEmail, LocalDateTime.now());
// Verify the signature immediately after signing
List<DigitalSignature> signatures = signature.verify();
if (signatures.isEmpty()) {
    throw new RuntimeException("Signature verification failed");
}
signature.sign(outputPath, approverOptions);
signature = new Signature(outputPath); // Reload the signed document
signature.sign(finalOutputPath, witnessOptions);
public DigitalSignOptions getOptionsForDocType(String docType) {
    DigitalSignOptions options = new DigitalSignOptions(certPath);
    if (docType.equals("contract")) {
        options.setVerticalAlignment(VerticalAlignment.Bottom);
        // Contract-specific settings
    } else if (docType.equals("invoice")) {
        options.setVerticalAlignment(VerticalAlignment.Top);
        // Invoice-specific settings
    }
    return options;
}
List<DigitalSignature> existingSignatures = signature.search(DigitalSignature.class);
if (!existingSignatures.isEmpty()) {
    System.out.println("Document already signed by: " + 
        existingSignatures.get(0).getContactInfo());
}

دروس ذات صلة