Bỏ qua để đến nội dung
getnextpdf.com

Enterprise phiên bản

Ký bằng hardware security module (PKCS#11)

NextPDF Enterprise ký một PDF bằng một khóa được giữ bên trong một hardware security module (HSM). Bạn trỏ signer tới một token PKCS#11 — một thẻ thông minh, một token Universal Serial Bus (USB), hoặc một HSM gắn mạng — và thao tác ký chạy trên thiết bị. Khóa riêng không bao giờ rời khỏi ranh giới token. Trang này ở mức hành vi: nó nêu signer làm gì, bạn cung cấp những gì, và việc lưu giữ khóa thôi là trách nhiệm của NextPDF ở đâu.

HSM signer được phân giải thông qua hợp đồng signer của Core, nên ứng dụng của bạn phụ thuộc vào hợp đồng, không phụ thuộc vào kiểu Enterprise cụ thể. Nó mở rộng cùng đường dẫn ký Cryptographic Message Syntax (CMS) mà Core dùng, ngoại trừ việc thao tác mã hóa được ủy thác cho token.

Các điều kiện tiên quyết được nêu trong front matter và được nhắc lại trong Điều kiện tiên quyết để bạn không bị bất ngờ giữa chừng tác vụ.

Năng lực này đi kèm trong NextPDF Enterprise (nextpdf/enterprise) và được kích hoạt bằng một phong bì giấy phép cấp Enterprise. Một lần triển khai không có quyền đó sẽ không nạp các lớp của năng lực này. So sánh các phiên bản và nhận giấy phép.

NextPDF Core kèm theo một trình ký CMS phần mềm giữ khóa trong tiến trình hoặc nhận một khóa thông qua hợp đồng chiến lược ký của Core; NextPDF Pro bổ sung các chiến lược ký bằng dịch vụ quản lý khóa (KMS) từ xa và trên đám mây. Việc lưu giữ khóa bằng phần cứng thông qua PKCS#11 là một năng lực Enterprise, không được Core hay Pro cung cấp.

Một token PKCS#11 phơi bày các đối tượng mã hóa — chứng chỉ và khóa riêng — phía sau một thư viện dùng chung của nhà cung cấp. Signer của Enterprise thích ứng thư viện đó:

  1. Nó mở thư viện dùng chung của token một lần cho mỗi tiến trình và lưu vào bộ nhớ đệm handle của module, vì PKCS#11 yêu cầu module được khởi tạo đúng một lần cho mỗi tiến trình.
  2. Nó mở một phiên trên slot đã cấu hình và đăng nhập bằng PIN được cung cấp. Việc đăng nhập xác thực người dùng trước bất kỳ thao tác khóa riêng nào, theo PKCS#11 v3.1 §5.6.8.
  3. Nó định vị chứng chỉ ký trên token theo nhãn, đọc chứng chỉ ở dạng Distinguished Encoding Rules (DER), và phát hiện thuật toán khóa công khai.
  4. Tại thời điểm ký, nó định vị khóa riêng theo nhãn — có thể khác với nhãn chứng chỉ trên một số token — và yêu cầu token tính chữ ký. Dữ liệu cần ký được truyền vào; khóa vẫn ở trên thiết bị.

Signer hỗ trợ RSA với padding PKCS#1 v1.5 (SHA-256, SHA-384, SHA-512), RSA với padding Probabilistic Signature Scheme (PSS) ở đó độ dài salt bằng độ dài bản băm, và Elliptic Curve Digital Signature Algorithm (ECDSA) với SHA-256, SHA-384, và SHA-512. Đường cong ECDSA và bản băm được ghép theo quy ước — P-256 với SHA-256, P-384 với SHA-384, P-521 với SHA-512 — theo cách ghép được khuyến nghị trong RFC 5480. Một token trả về một chữ ký ECDSA dưới dạng một sự nối thô của hai số nguyên; signer chuyển nó sang dạng mã hóa DER mà PDF và OpenSSL kỳ vọng.

Đối với việc tạo chữ ký, một khóa RSA dài ít nhất 2048 bit và một bậc đường cong ECDSA ít nhất 224 bit là các mức tối thiểu chấp nhận được theo NIST SP 800-131A Rev.2 §3. Hãy cấp phát khóa token của bạn ở các kích thước đó hoặc cao hơn.

Một đường dẫn OpenSSL-engine thay thế tồn tại cho các token được engine hậu thuẫn. Trên OpenSSL 3.x, extension OpenSSL của PHP không phơi bày application programming interface (API) của engine, nên lớp engine bị deprecated; tuyến được engine hậu thuẫn được hỗ trợ chạy binary dòng lệnh OpenSSL. Hãy ưu tiên đường dẫn PKCS#11 trực tiếp ở nơi token của bạn có một thư viện PKCS#11.

Quyết định then chốt là khóa riêng không bao giờ rời khỏi token. Vì vậy signer ủy thác thao tác mã hóa cho thiết bị và chỉ di chuyển dữ liệu cần ký qua ranh giới PKCS#11. Nó không bao giờ đọc hay tái dựng tài liệu khóa trong bộ nhớ PHP. Nó phân giải thông qua hợp đồng HsmSignerInterface của Core thay vì một kiểu Enterprise cụ thể, nên mã ký là giống hệt nhau cho dù khóa nằm trong phần mềm, một cloud KMS, hay một token phần cứng. Nó lưu đệm handle của module một lần cho mỗi tiến trình vì PKCS#11 khởi tạo mỗi module đúng một lần cho mỗi tiến trình, rồi chuyển đầu ra ECDSA thô của token sang DER để các trình xác thực thấy dạng mã hóa mà chúng kỳ vọng. Chính việc lưu giữ, chứ không phải sự tiện lợi, định hình cách làm: ranh giới tin cậy vẫn ở rìa thiết bị.

Bối cảnh thiết kế: Ký được HSM hậu thuẫn.

Trước khi bạn ký bằng một HSM, hãy xác nhận từng mục:

  1. Cài đặt NextPDF Core và gói Enterprise: composer require nextpdf/core:^3composer require nextpdf/enterprise.
  2. Giữ một giấy phép NextPDF Enterprise đang hoạt động; phân giải gói bằng thông tin đăng nhập giấy phép của bạn trên Private Packagist.
  3. Cài đặt thư viện dùng chung PKCS#11 của nhà cung cấp token trên máy chủ (ví dụ một .so trên Linux hoặc một .dll trên Windows) và ghi lại đường dẫn tuyệt đối của nó, số slot, và các nhãn đối tượng.
  4. Nạp extension PHP ext-pkcs11. Nó không đi kèm với PHP tiêu chuẩn và phải được cài đặt riêng. Bộ khởi tạo signer phát sinh một lỗi thao tác có kiểu khi extension vắng mặt.

Hãy cung cấp các đầu vào sau cho signer:

  • Đường dẫn thư viện — đường dẫn tuyệt đối tới thư viện dùng chung PKCS#11 của nhà cung cấp.
  • Mã định danh slot — số slot của token, thường là 0.
  • PIN — PIN của token. Hãy coi nó là một bí mật: cung cấp nó từ trình quản lý bí mật của bạn, không bao giờ từ mã nguồn hay nhật ký. Signer đánh dấu tham số PIN là nhạy cảm để nó bị loại khỏi stack trace và việc tuần tự hóa.
  • Nhãn chứng chỉ — nhãn của đối tượng chứng chỉ trên token.
  • Nhãn khóa — nhãn của đối tượng khóa riêng, khi nó khác với nhãn chứng chỉ.
  • Chuỗi — các chứng chỉ trung gian tùy chọn ở dạng DER, khi token không giữ chúng.

Hãy kiểm tra tính khả dụng của token trước khi bạn dựng signer. Việc dựng đọc chứng chỉ từ token, nên một slot hay nhãn bị cấu hình sai sẽ trượt sớm với một lỗi có kiểu thay vì tại thời điểm ký.

  1. Xác nhận runtime hỗ trợ PKCS#11 bằng cách kiểm tra tính khả dụng của extension. Đừng dựng signer khi extension vắng mặt.
  2. Đọc PIN từ trình quản lý bí mật của bạn vào một biến không bao giờ được ghi nhật ký.
  3. Dựng HSM signer với đường dẫn thư viện, slot, PIN, và các nhãn. Việc dựng đăng nhập và đọc chứng chỉ.
  4. Truyền signer tới trình điều phối ký của Core thông qua HsmSignerInterface. Trình điều phối tính byte range, dựng các thuộc tính đã ký CMS, trao dữ liệu cho token, và lắp ráp PDF đã ký.
  5. Bắt lỗi cụ thể nhất, ghi nhật ký một thông điệp cấu trúc không kèm PIN, và ném lại.
examples/contracts/hsm-signer-availability.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HsmSignerInterface;
/**
* Build a hardware-token signer only when the runtime supports it.
*
* The concrete PKCS#11 signer is resolved through the Core contract so the
* caller depends on the interface, not the Enterprise implementation type.
* The PIN arrives from a secret resolver; it is never written to source.
*
* @param callable(): bool $pkcs11Available Reports ext-pkcs11 availability.
* @param callable(): HsmSignerInterface $signerFactory Builds the configured token signer.
*
* @throws \RuntimeException When the PKCS#11 extension is not loaded.
*
* @return HsmSignerInterface The token signer, ready for the Core orchestrator.
*/
function resolveHsmSigner(callable $pkcs11Available, callable $signerFactory): HsmSignerInterface
{
if ($pkcs11Available() !== true) {
throw new \RuntimeException(
'PKCS#11 signing requires the ext-pkcs11 extension; install it before signing.',
);
}
return $signerFactory();
}

Phần nối dây sản phẩm — danh sách đối số khởi tạo chính xác và các kiểu ngoại lệ có kiểu — được ghi trong tài liệu tham chiếu chuyên sâu về HSM.

examples/contracts/hsm-sign-guarded.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HsmSignerInterface;
use NextPDF\Exception\NextPdfException;
use Psr\Log\LoggerInterface;
final readonly class HsmSigningService
{
public function __construct(
private HsmSignerInterface $signer,
private LoggerInterface $logger,
) {}
/**
* Sign data on the token through the Core HSM contract.
*
* The byte range is computed by the engine, never accepted from the
* caller. The token performs the signing operation; the private key
* does not leave the device.
*
* @param string $data The bytes the orchestrator hands to the token.
* @param string $algorithm The OpenSSL-style signing algorithm identifier.
*
* @throws NextPdfException When the token operation fails.
*
* @return string The raw signature bytes returned by the token.
*/
public function sign(string $data, string $algorithm): string
{
try {
return $this->signer->sign($data, $algorithm);
} catch (NextPdfException $e) {
// Structural message only — never the PIN or key material.
$this->logger->error('HSM signing failed', ['reason' => $e->getMessage()]);
throw $e;
}
}
}

Hãy xác nhận kết quả theo cách mà một bên xác minh sẽ làm:

  1. Đọc lại chứng chỉ signer và chuỗi ở dạng DER từ signer và xác nhận chúng khớp với chứng chỉ đã được cấp phát trên token.
  2. Mở PDF đã ký trong một trình xác thực được cấu hình với các trust anchor của bạn và xác nhận chữ ký được báo cáo là còn nguyên vẹn về mặt mã hóa. Một chữ ký được tạo ra không phải là một chữ ký đã được xác minh; quyết định tin cậy thuộc về bên xác minh và các trust anchor của bên đó, không phải bên tạo ra.
  3. Đối với một chữ ký ECDSA, hãy xác nhận chữ ký được nhúng được mã hóa DER — signer chuyển đổi đầu ra thô của token cho bạn, nên một trình xác thực từ chối dạng nối thô vẫn nên chấp nhận chữ ký được nhúng.
  4. Xác nhận không có PIN, nhãn token, hay tài liệu khóa nào xuất hiện trong nhật ký ứng dụng của bạn.
  • Khóa vẫn ở trên token. Dữ liệu cần ký được trao cho token; thao tác ký chạy bên trong ranh giới token. Khóa riêng không bao giờ được nạp vào bộ nhớ PHP.
  • PIN là một bí mật. Nó là một tham số khởi tạo nhạy cảm, bị loại khỏi nhật ký và việc tuần tự hóa. Hãy cung cấp nó từ một trình quản lý bí mật. Việc tái xác thực thất bại lặp lại có thể khóa PIN tại token; token, không phải NextPDF, thực thi chính sách đó.
  • Fail-closed. Một lỗi token hay HSM sẽ phát sinh một ngoại lệ có kiểu. Signer không tạo ra một kết quả chưa ký hay ký một phần và không bao giờ thay thế bằng một thuật toán yếu hơn.
  • Độ mạnh thuật toán. Hãy cấp phát các khóa RSA dài ít nhất 2048 bit và các đường cong ECDSA bậc ít nhất 224 bit, các mức tối thiểu chấp nhận được cho việc tạo chữ ký theo NIST SP 800-131A Rev.2 §3.
  • Ký hậu lượng tử là thử nghiệm và tắt theo mặc định. Một đường dẫn hậu lượng tử tồn tại phía sau một cờ tùy chọn bật tường minh. Các hồ sơ lưu trữ dài hạn chuẩn PDF Advanced Electronic Signatures (PAdES) chưa nhận diện các bộ hậu lượng tử, và hầu hết trình xem từ chối chúng khi xác thực. Đừng bật nó cho các chữ ký PAdES sản phẩm.

Trang này liên quan đến việc ký mã hóa và tích hợp hardware-security-module. Mọi nguồn quy phạm đều được diễn giải lại; không có văn bản quy phạm nào được sao chép nguyên văn. ### Ranh giới lưu giữ khóa

NextPDF Enterprise tích hợp với một token PKCS#11 hoặc HSM. Nó không lưu trữ, tạo, hay bảo đảm tính bảo mật của khóa ký. Tính bảo mật của khóa phụ thuộc vào token hoặc HSM, vào lần triển khai, và vào người vận hành — không chỉ phụ thuộc vào riêng NextPDF Enterprise. Bạn chịu trách nhiệm cấp phát token, xử lý PIN, cấu hình slot, và bảo vệ mạng cho một HSM gắn mạng.

  • Extension vắng mặt. Việc dựng PKCS#11 signer phát sinh một ngoại lệ thao tác có kiểu khi ext-pkcs11 không được nạp. Hãy kiểm tra tính khả dụng trước.
  • Không tìm thấy chứng chỉ hay khóa theo nhãn. Việc dựng hoặc ký phát sinh một ngoại lệ có kiểu nêu tên đối tượng còn thiếu. Hãy xác nhận nhãn và slot.
  • Đã đăng nhập. Khi nhiều thể hiện signer chia sẻ một module đã được lưu đệm cho cùng một slot, signer đăng xuất và đăng nhập lại để cung cấp một lần xác minh PIN mới — yêu cầu bởi các token personal-identity-verification có chính sách “PIN mỗi lần”.
  • Thuật toán không được hỗ trợ. Việc yêu cầu một thuật toán mà signer không ánh xạ sẽ phát sinh một lỗi đối số thay vì ký bằng một thuật toán thay thế.
  • Network HSM không truy cập được. Một lỗi mạng hay thiết bị sẽ phát sinh một ngoại lệ có kiểu; signer không bao giờ âm thầm tạo ra một tài liệu chưa ký.

Trang này chỉ ghi lại hành vi quan sát được từ bên ngoài và bề mặt API công khai được hỗ trợ. Các đường dẫn namespace nội bộ, các lớp trợ giúp, các bảng cơ chế, các tên tệp runbook, và các tiền tố phiếu nằm ngoài phạm vi.