Pendahuluan & Motivasi
Saat menerapkan tanda tangan digital dalam sistem kelas perusahaan, keamanan tidak dapat dinegosiasikan.
Menyimpan sertifikat dalam file PFX atau P12 lokal memang praktis, tetapi
menyebabkan kunci pribadi dapat diekstraksi atau dikompromikan. Sebaliknya,
PKCS#11 hardware tokens (seperti dongle USB, kartu pintar, dan HSM)
menyimpan kunci di dalam batas yang tahan gangguan, memastikan kunci tidak pernah keluar
dari perangkat.
Postingan ini menunjukkan cara menggunakan GroupDocs.Signature for .NET bersama Pkcs11Interop untuk menandatangani dokumen PDF dengan token hardware. Pendekatan ini menggabungkan kemudahan dan kepatuhan: GroupDocs menangani semua pengemasan tingkat PDF (field tanda tangan, perhitungan digest, penyisipan), sementara token melakukan penandatanganan kriptografis yang sebenarnya.
⚠️ Pemberitahuan Implementasi Awal
Solusi ini saat ini disediakan sebagai implementasi awal untuk menggunakan dongle tanda tangan digital PKCS#11 dengan GroupDocs.Signature.
Meskipun memungkinkan penandatanganan dokumen dengan token hardware, kami sangat menyarankan melakukan pengujian tambahan di lingkungan Anda sendiri untuk memastikan bahwa solusi ini memenuhi persyaratan kepatuhan dan keamanan Anda.
Kami sangat menghargai umpan balik, hasil pengujian, dan saran perbaikan Anda.
Tantangan: Menjembatani PKCS#11 dengan Penandatanganan PDF
Mengintegrasikan token PKCS#11 ke dalam alur kerja penandatanganan dokumen memiliki beberapa tantangan yang tidak sepele:
- Kompleksitas Tingkat Rendah – API PKCS#11 (Cryptoki) memerlukan pengelolaan slot, sesi, handle, dan atribut untuk menemukan kunci pribadi yang tepat.
- Pengemasan Tingkat PDF – Menandatangani PDF lebih dari sekadar menandatangani byte: perpustakaan harus menghitung digest yang benar atas rentang byte yang dipilih, membungkus tanda tangan dalam kontainer CMS/PKCS#7, menyertakan timestamp, dan menyisipkan informasi validasi.
- Variasi Vendor – Token/modul vendor yang berbeda mungkin memerlukan pemetaan atribut khusus atau middleware tambahan.
- Kepatuhan & Auditabilitas – Sistem produksi memerlukan penanganan PIN yang kuat, kontrol siklus hidup sesi, pemulihan kesalahan, dan pencatatan.
Proyek contoh ini mengatasi hal‑hal tersebut dengan menggabungkan antarmuka ICustomSignHash di GroupDocs.Signature dengan Pkcs11Interop untuk memindahkan penandatanganan ke token, sementara membiarkan GroupDocs mengelola struktur PDF.
Apa yang Dilakukan Proyek Contoh Ini
- Menunjukkan penandatanganan dokumen PDF menggunakan token PKCS#11 (dongle, kartu pintar, HSM).
- Mendukung fallback ke Windows certificate store: jika sebuah sertifikat terpasang di Windows, kode dapat menggunakannya sebagai alternatif.
- Mengimplementasikan custom hash signing: GroupDocs menghitung digest; token hanya menandatangani hash tersebut.
- Menjaga kunci pribadi tetap berada di hardware sepanjang waktu — tidak pernah diekspor.
- Membungkus logika token (sesi, pencarian kunci, penandatanganan) dalam
Pkcs11DigitalSigner.cs - Menyediakan logika bantu dalam
Helpers.cs(misalnya, pencarian sertifikat di Windows store). - Konfigurasi terpusat di
Settings.cs. - Berfungsi sebagai implementasi referensi yang dapat Anda sesuaikan dengan lingkungan Anda.
Persiapan & Prasyarat
Prasyarat
- .NET 6.0 atau lebih tinggi (atau .NET Framework 4.6.2)
- Perpustakaan PKCS#11 (DLL) yang valid dari vendor token Anda
- Token hardware (dongle USB, kartu pintar, atau HSM) dengan sertifikat yang valid
- GroupDocs.Signature for .NET (versi percobaan atau berlisensi)
- Perpustakaan Pkcs11Interop
Instalasi
git clone https://github.com/groupdocs-signature/esign-documents-with-pkcs11-using-groupdocs-signature-dotnet.git
cd esign-documents-with-pkcs11-using-groupdocs-signature-dotnet
dotnet restore
Buka solusi di Visual Studio atau IDE pilihan Anda, pastikan semua dependensi terpasang.
Penjelasan Struktur Repositori
GroupDocs.Signature-for-.NET-PKCS11-Sample/
├── GroupDocs.Signature-for-.NET-PKCS11-Sample.csproj # File proyek
├── Program.cs # Titik masuk dan alur penggunaan
├── Settings.cs # Konfigurasi PKCS#11 / token
├── Helpers.cs # Fungsi utilitas (Windows store, penyaringan sertifikat)
├── Pkcs11DigitalSigner.cs # Mengimplementasikan ICustomSignHash via PKCS#11
└── README.md # Penjelasan & instruksi penggunaan
- Program.cs – mengatur alur penandatanganan; mendemonstrasikan alur berbasis token maupun alur sertifikat Windows.
- Settings.cs – berisi konstanta/tempat penampung untuk
Pkcs11LibraryPath,TokenPin, danCertificateSubject. - Helpers.cs – berisi kode untuk menemukan sertifikat di Windows store berdasarkan nama subjek (digunakan untuk alur fallback).
- Pkcs11DigitalSigner.cs – logika inti: memuat modul PKCS#11, membuka sesi, menemukan objek kunci pribadi, menandatangani digest, dan
mengembalikan
X509Certificate2atau implementasi callback tanda tangan. - README.md – memberikan gambaran, tantangan, dan instruksi penggunaan (yang dilengkapi oleh blog ini).
Penjelasan Kode & Panduan
Settings.cs
public static class Settings
{
public const string Pkcs11LibraryPath = "<PKCS11_LIBRARY_PATH>";
public const string TokenPin = "<TOKEN_PIN>";
public const string CertificateSubject = "<CERT_SUBJECT>";
}
Bagian ini memisahkan detail konfigurasi sehingga mudah diganti di lingkungan penerapan Anda.
Pkcs11DigitalSigner.cs — Alur Tingkat Tinggi
public class Pkcs11DigitalSigner : ICustomSignHash
{
public byte[] SignHash(byte[] hash)
{
// This method is invoked by GroupDocs.Signature when it needs the token to sign a hash
using (var pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, AppType.SingleThreaded))
{
// Load module, open session, login with PIN, find key and perform signing
}
}
public X509Certificate2 GetCertificateFromPkcs11()
{
// Retrieves the public certificate from the token so the signing options can be configured
}
}
SignHashadalah metode utama: ia menerima digest yang dihitung oleh GroupDocs, lalu menggunakan API PKCS#11 untuk menandatanganinya.GetCertificateFromPkcs11mengambil sertifikat (dengan kunci publik) yang disimpan di token sehingga metadata tanda tangan menjadi tepat.
Program.cs — Alur Penggunaan
class Program
{
static void Main()
{
string inputFile = "sample.pdf";
string outputFile = "signed.pdf";
// (1) PKCS#11 signing
var tokenSigner = new Pkcs11DigitalSigner();
var cert = tokenSigner.GetCertificateFromPkcs11();
using (var signature = new Signature(inputFile))
{
var options = new DigitalSignOptions(cert)
{
Comments = "Signed with PKCS#11 token",
SignTime = DateTime.Now,
CustomSignHash = tokenSigner // link token-based signing
};
signature.Sign(outputFile, options);
}
// (2) Windows certificate store fallback (optional)
// var storeCert = Helpers.GetCertificateFromWindowsStore(Settings.CertificateSubject);
// using (var signature2 = new Signature(inputFile))
// {
// var options2 = new DigitalSignOptions(storeCert) { ... };
// signature2.Sign("signed_store.pdf", options2);
// }
}
}
Poin penting:
- Properti
CustomSignHashpadaDigitalSignOptionsdiatur ketokenSigner, sehingga GroupDocs dapat mendelegasikan penandatanganan hash sebenarnya ke token. - Alur fallback (dikomentasikan) menunjukkan cara beralih ke sertifikat Windows store ketika token hardware tidak tersedia.
Kasus Penggunaan & Skenario Dunia Nyata
- India & Dongle USB Sertifikat CA
Di India, banyak eSignature yang mengikat secara hukum mengharuskan sertifikat disimpan dalam dongle USB yang dikeluarkan oleh otoritas bersertifikat. Contoh ini memungkinkan aplikasi (mis. gateway dokumen, portal) berintegrasi langsung dengan dongle tersebut. - Alur Kerja Dokumen Perusahaan
Untuk sistem internal seperti manajemen kontrak atau alur persetujuan, penandatanganan hardware memastikan bahwa pengguna yang tidak berwenang tidak dapat memalsukan tanda tangan dokumen. - Penandatanganan Legal / Kepatuhan
Pemerintah dan industri yang diatur seringkali mengharuskan tanda tangan berasal dari kunci yang dikendalikan hardware. Integrasi ini membantu memenuhi tuntutan audit dan kepatuhan yang ketat.
Kesalahan Umum & Pemecahan Masalah
- Path perpustakaan salah → Path DLL PKCS#11 harus sesuai dengan modul vendor token Anda (mis.
softhsm2.dll,cryptoki.dll). - PIN terkunci atau gagal → Entri PIN yang salah berulang kali dapat mengunci token; periksa kebijakan vendor.
- Kunci tidak ditemukan → Pastikan subjek sertifikat yang diberikan sudah tepat; token harus berisi sertifikat dengan subjek yang cocok.
- Driver atau middleware hilang → Beberapa token memerlukan pemasangan driver vendor sebelum Pkcs11Interop dapat berkomunikasi.
- Masalah threading → Operasi PKCS#11 mungkin tidak thread‑safe; gunakan konteks single‑threaded kecuali vendor mendukung multiple.
- Timeout atau reset sesi → Operasi yang lama dapat menyebabkan sesi tertutup atau timeout; pastikan penanganan sesi dan pembersihan yang tepat.
Keamanan & Praktik Terbaik
- Jangan pernah menuliskan rahasia produksi secara keras (PIN, path perpustakaan); gunakan konfigurasi aman atau manajemen rahasia.
- Gunakan PIN yang kuat dan rotasi bila kebijakan mengizinkan.
- Catat operasi dan kesalahan (tanpa mencatat PIN yang sensitif).
- Batasi sesi token dan logout segera setelah penandatanganan.
- Validasi tanda tangan setelah penandatanganan (pemeriksaan rantai, timestamp).
- Uji di berbagai lingkungan dan tipe token (dongle/kartu pintar/HSM).
Langkah Selanjutnya & Sumber Daya
Siap mencobanya sendiri? Clone repositori, perbarui placeholder, dan jalankan contoh. Topik yang mungkin ingin Anda jelajahi selanjutnya:
- Custom Hash Signing (mendelegasikan digest + penandatanganan ke token)
- Timestamping & LTV / DSS embedding
- Iterative signing (multiple signatures in one document)
- Integrasi dengan layanan HSM remote atau penyimpanan token berbasis cloud