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

Enterprise phiên bản

Ký HSM — Tài liệu tham chiếu chuyên sâu

Trang này là tài liệu tham chiếu chuyên sâu cho bề mặt ký HSM của NextPDF Enterprise. Nó bao phủ ba kiểu công khai. NextPDF\Enterprise\Security\Signature\Hsm\Pkcs11Signer ký thông qua một token PKCS#11 qua extension ext-pkcs11. NextPDF\Enterprise\Security\Signature\Hsm\OpenSslCliSigner ký thông qua binary openssl trong một tiến trình con, dành cho các khóa dựa trên provider hoặc engine mà PHP ext-openssl không thể nạp. NextPDF\Enterprise\Security\Signature\Hsm\Provider\HsmSignerProviderAdapter phơi bày một trong hai lớp cụ thể như một SignerProviderInterface hợp nhất. Trên mọi đường đi, khóa riêng tư vẫn nằm bên trong ranh giới token; NextPDF chuyển giao các byte cần ký và nhận lại chữ ký. Đường hậu lượng tử (signPqs) là một bản xem trước: nó bị vô hiệu hóa theo mặc định, không mang bất kỳ tuyên bố tuân thủ nào, và không có đường xác minh được hỗ trợ trong các trình xác thực PDF hiện nay. NextPDF không nắm giữ chứng nhận nào và không cấp chứng nhận nào; hỗ trợ không đồng nghĩa với tuân thủ, và tuân thủ không đồng nghĩa với chứng nhận.

Năng lực này đi kèm trong NextPDF Enterprise (nextpdf/enterprise) và kích hoạt bằng một phong bì giấy phép hạng Enterprise. Một triển khai không có quyền hưởng đó 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.

Cả ba kiểu đều nằm trong NextPDF\Enterprise\Security\Signature\Hsm; bộ điều hợp đặt trong không gian tên con Provider của nó. Cả hai bộ ký đều hiện thực hợp đồng Core NextPDF\Contracts\HsmSignerInterface.

Ký hiệuTham sốHành vi mặc địnhTrả vềNém hoặc thất bại vớiGhi chú
Pkcs11Signer::__construct()string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = nullMở thư viện của nhà cung cấp, đăng nhập vào slot, và nạp chứng thư cùng metadata thuật toán khóa từ tokenHsmOperationException khi thiếu ext-pkcs11 hoặc truy cập token thất bạiMột handle module được cache theo mỗi đường thư viện trên mỗi tiến trình; PIN và các nhãn là #[SensitiveParameter]
Pkcs11Signer::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'Ký trên token; đầu ra ECDSA thô được chuyển sang DER ECDSA-Sig-Valuestring các byte chữ ký thôHsmOperationException (không tìm thấy khóa, token lỗi); InvalidArgumentException (thuật toán không được ánh xạ); ngoại lệ cổng FIPS trước khi ký khi có gắn enforcerTập thuật toán đóng; xem Hợp đồng hành vi
Pkcs11Signer::signPqs()string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = trueBị từ chối trừ khi $enablePostQuantum đã được đặt; điều phối cơ chế PQ PKCS#11 tạm thờistring các byte chữ ký thôHsmOperationException (bị vô hiệu, token lỗi, độ dài chữ ký không khớp); InvalidArgumentException (context vượt quá 255 byte)Xem trước; không có tuyên bố tuân thủ; các định danh cơ chế là tạm thời
Pkcs11Signer::isPostQuantumEnabled()KhôngBáo cáo cờ opt-in của hàm khởi tạoboolKhông
Pkcs11Signer::getCertificateDer()KhôngTrả về chứng thư của bộ ký đọc từ tokenstring (DER)KhôngĐược nạp một lần khi khởi tạo
Pkcs11Signer::getCertificateChainDer()KhôngTrả về các chứng thư trung gian do hàm khởi tạo cung cấparray<string> (DER)KhôngLoại trừ chứng thư của bộ ký
OpenSslCliSigner::__construct()string $keyUri, string $certPath, string $pin, array $extraCertPaths = [], OpenSslCliBackend $backend = OpenSslCliBackend::Auto, string $opensslBinary = 'openssl', int $timeoutSeconds = 30, ?string $modulePath = null, ?string $configPath = null, bool $legacyPinDelivery = false, ?FipsSignatureEnforcer $fipsEnforcer = nullXác minh proc_open, thăm dò binary và phiên bản, phân giải backend, và nạp các chứng thưHsmOperationException (proc_open bị vô hiệu, thiếu tệp module/config/chứng thư, binary lỗi, không có backend); InvalidArgumentException (pin-value bên trong $keyUri)OpenSslCliBackend::Auto ưu tiên provider OpenSSL 3.x, rồi tới engine
OpenSslCliSigner::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'Chạy openssl dgst trong một tiến trình con; theo mặc định PIN đi qua một tệp pin-source phù du 0600string các byte chữ ký thôHsmOperationException (hết thời gian, PIN bị từ chối, không tìm thấy khóa, nạp module thất bại, đầu ra rỗng, tệp pin lỗi); InvalidArgumentException (thuật toán không được ánh xạ); ngoại lệ cổng FIPS trước khi kýTiến trình con bị hủy sau $timeoutSeconds; stderr được che kín trước khi lọt vào thông điệp
Bề mặt accessor của OpenSslCliSignerKhôngKết quả khởi tạo chỉ đọcstring / array<string> / OpenSslCliBackendKhônggetCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion
HsmSignerProviderAdapter::__construct()HsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15Bọc một lớp HSM cụ thể thành một SignerProviderInterfaceKhôngQuy ước id provider: pkcs11-{module-id}, openssl-cli
HsmSignerProviderAdapter::providerId()KhôngTrả về id do hàm khởi tạo cung cấpnon-empty-stringKhông
HsmSignerProviderAdapter::supportsAlgorithm()SignatureAlgorithm $algoÁnh xạ enum sang tên kiểu OpenSSL, rồi giao với tập cho phép của backendboolKhôngTừ chối các thuật toán chỉ-digest; các id openssl-engine không quảng bá gì
HsmSignerProviderAdapter::sign()string $data, ?string $keyVersion = nullĐiều phối qua bộ ký được bọc với thuật toán đã cấu hìnhnon-empty-stringKeyManagementException ($keyVersion khác null); SignatureFailedException (thuật toán không ánh xạ được, driver lỗi, chữ ký rỗng)Hợp đồng SPI fail-closed; mọi lỗi driver được bộc lộ có kiểu
public function __construct(private readonly string $libraryPath, private readonly int $slotId, #[SensitiveParameter] private readonly string $pin, #[SensitiveParameter] private readonly string $certLabel, #[SensitiveParameter] private readonly ?string $keyLabel = null, array $chainDer = [], private readonly bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null)
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public function signPqs(string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true): string
public function isPostQuantumEnabled(): bool
public function getCertificateDer(): string
public function getCertificateChainDer(): array
public function __construct(private string $keyUri, string $certPath, #[SensitiveParameter] private string $pin, array $extraCertPaths = [], private OpenSslCliBackend $backend = OpenSslCliBackend::Auto, private string $opensslBinary = 'openssl', private int $timeoutSeconds = 30, private ?string $modulePath = null, private ?string $configPath = null, private bool $legacyPinDelivery = false, private ?FipsSignatureEnforcer $fipsEnforcer = null)
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public function getCertificateDer(): string
public function getCertificateChainDer(): array
public function getPublicKeyAlgorithm(): string
public function getCertificatePem(): string
public function getResolvedBackend(): OpenSslCliBackend
public function getOpensslVersion(): string
public function __construct(private HsmSignerInterface $hsm, private string $providerId, private SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15)
public function providerId(): string
public function supportsAlgorithm(SignatureAlgorithm $algo): bool
public function sign(string $data, ?string $keyVersion = null): string
  • Lưu giữ khóa. Khóa riêng tư không bao giờ rời khỏi ranh giới token. Pkcs11Signer ủy thác thao tác cho token; OpenSslCliSigner truyền một tham chiếu khóa — một URI PKCS#11 — cho tiến trình con openssl. Không bộ ký nào có thể xuất khóa.
  • Phiên và đăng nhập. Pkcs11Signer cache một handle module PKCS#11 theo mỗi đường thư viện trên mỗi tiến trình, bởi vì giao diện token phải được khởi tạo đúng một lần trên mỗi tiến trình. Mỗi thao tác mở một phiên và đăng nhập bằng PIN; việc đăng nhập xác thực người dùng trước bất kỳ sử dụng khóa riêng tư nào (PKCS#11 v3.1 §5.6.8). Khi slot báo có một phiên đăng nhập hiện hữu, bộ ký đăng xuất rồi đăng nhập lại, nhờ đó các token đòi hỏi PIN mới cho mỗi thao tác sẽ nhận được nó.
  • Tập thuật toán (đóng). Cả hai bộ ký chấp nhận đúng: sha256WithRSAEncryption, sha384WithRSAEncryption, sha512WithRSAEncryption; RSASSA-PSS, RSASSA-PSS-SHA256, RSASSA-PSS-SHA384, RSASSA-PSS-SHA512; ecdsa-with-SHA256, ecdsa-with-SHA384, ecdsa-with-SHA512. Pkcs11Signer chấp nhận thêm ecdsa-raw. Bất kỳ định danh nào khác đều làm phát sinh InvalidArgumentException — không có thuật toán thay thế nào từng được ký.
  • Ràng buộc salt của PSS. Với mọi biến thể PSS, độ dài salt bằng độ dài digest — 32, 48, hoặc 64 byte — và các tham số hash và MGF khớp với digest đã chọn. Điều này tuân theo cấu trúc tham số cơ chế PSS, nơi độ dài salt điển hình là độ dài hash của thông điệp (PKCS#11 v3.1 §6.1.9). Cả hai bộ ký áp dụng cùng cách ghép cặp, nên một cấu hình hợp lệ trên một backend cũng hợp lệ trên backend kia.
  • Chuyển đổi ECDSA. Một token trả về chữ ký ECDSA dưới dạng phép ghép thô, đệm-không của rs (PKCS#11 v3.1 §6.3.1). Pkcs11Signer::sign() chuyển đầu ra đó sang dạng ECDSA-Sig-Value mã hóa DER mà các trình xác thực PDF và OpenSSL trông đợi. Phía gọi không bao giờ phải xử lý dạng thô.
  • Truyền PIN (đường CLI). Ở mặc định an toàn, PIN được ghi vào một tệp phù du được tạo riêng với quyền chỉ-chủ-sở-hữu, được tham chiếu qua thuộc tính pin-source của URI PKCS#11, và được xóa liên kết sau khi tiến trình con thoát. Trong chế độ này PIN không được đặt trên dòng lệnh và không được xuất ra môi trường của tiến trình con. Với $legacyPinDelivery = true, PIN được nhúng dưới dạng pin-value trong URI, điều này quan sát được trên dòng lệnh của tiến trình; chế độ này chỉ dùng khi opt-in.
  • Kỷ luật tiến trình con. OpenSslCliSigner sinh ra binary với một mảng đối số — không có nội suy shell — thực thi $timeoutSeconds, hủy tiến trình con khi hết hạn, và phân loại stderr thành các lỗi có kiểu. Các bí mật được che kín khỏi stderr trước khi nó được trích dẫn trong một thông điệp ngoại lệ.
  • Ngữ nghĩa của bộ điều hợp. Một token HSM không có khái niệm phiên bản khóa được quản lý; khóa trên token chính là phiên bản. Do đó HsmSignerProviderAdapter::sign() từ chối bất kỳ $keyVersion khác null nào với KeyManagementException thay vì bỏ qua nó. supportsAlgorithm() giao ánh xạ enum với tập chấp nhận của backend được bọc, nên bộ điều hợp không bao giờ quảng bá một cơ chế mà backend sẽ từ chối lúc ký. Một chữ ký rỗng từ driver làm phát sinh SignatureFailedException.
  • Xem trước hậu lượng tử. signPqs() bị chắn sau cờ khởi tạo $enablePostQuantum và từ chối chạy nếu không. Chuỗi context bị giới hạn ở 255 byte, khớp với giới hạn context của ML-DSA (FIPS 204). Chữ ký trả về phải khớp chính xác độ dài byte của bộ tham số Pkcs11PqsAlgorithm được chọn, nếu không lời gọi sẽ thất bại. Các định danh cơ chế theo một extension PQ PKCS#11 tạm thời và chưa chính thức. Các hồ sơ PAdES không nhận diện các bộ hậu lượng tử, phần lớn trình xác thực PDF từ chối các chữ ký như vậy, và NextPDF không cung cấp đường xác minh nào cho chúng. Không có tuyên bố tuân thủ nào.
  • Khởi tạo Pkcs11Signer mà không có ext-pkcs11 làm phát sinh HsmOperationException ngay lập tức; extension này không đi kèm với các bản phân phối PHP chuẩn.
  • Một nhãn chứng thư hoặc nhãn khóa riêng tư không khớp với đối tượng nào trên token làm phát sinh HsmOperationException nêu tên lớp đối tượng bị thiếu. Trên một số token, nhãn khóa có thể khác hợp lệ so với nhãn chứng thư.
  • Các lần đăng nhập thất bại lặp lại có thể khóa PIN tại token; token thực thi chính sách đó, không phải NextPDF. Các token có khóa yêu cầu xác thực cho mỗi lần dùng sẽ nhận một phiên đăng nhập mới qua đường đăng-xuất-rồi-thử-lại (PKCS#11 v3.1, ngữ nghĩa always-authenticate).
  • OpenSslCliSigner từ chối một $keyUri đã chứa sẵn pin-value lúc khởi tạo, theo hướng fail-closed, vì cách truyền đó sẽ bỏ qua đường PIN an toàn.
  • Trên Windows, chế độ tệp pin an toàn thất bại theo hướng fail-closed với HsmOperationException: các bit quyền tệp không thể hạn chế các cấp quyền đọc ACL ở đó, nên bộ ký từ chối để lại một PIN dạng rõ tại ACL của thư mục tạm. Truyền PIN kiểu cũ là phương án thay thế, có tài liệu, dạng opt-in cho các host Windows đáng tin cậy.
  • Tự động dò backend yêu cầu OpenSSL 3.x cho đường provider; LibreSSL không bao giờ phân giải tới provider. Khi cả thăm dò provider lẫn engine đều không thành công, việc khởi tạo thất bại với HsmOperationException thay vì hoãn lỗi tới lúc ký.
  • Một tiến trình con vượt quá $timeoutSeconds bị chấm dứt và báo cáo là hết thời gian; một tiến trình con thoát sạch với đầu ra rỗng được báo cáo là thất bại chữ-ký-rỗng. Không điều kiện nào có thể tạo ra một tài liệu được ký một phần.
  • Một chữ ký hậu lượng tử có độ dài byte không khớp với bộ tham số đã chọn bị từ chối trước khi nó có thể đến bước mã hóa CMS.
  • HsmSignerProviderAdapter với id provider openssl-engine đã ngừng dùng không quảng bá thuật toán nào, nên một cấu hình cũ thất bại tại bước chọn provider thay vì lúc ký.

Cả hai bộ ký chấp nhận một FipsSignatureEnforcer tùy chọn. Khi có gắn một cái, chế độ FIPS đang hoạt động cho bộ ký đó: sign() từ chối một thuật toán chữ ký không được phép hoặc một khóa dưới sàn trước khi bất kỳ thao tác ký nào của token hoặc tiến trình con diễn ra. Các sàn tuân theo bảng tạo-sinh-chữ-ký — module RSA dưới 2048 bit và bậc ECDSA dưới 224 bit đều không được phép (NIST SP 800-131A Rev.2 §3 Table 2). Không có enforcer, hành vi không đổi. Cổng chỉ bao phủ đường sign() cổ điển; signPqs() được điều chỉnh bởi cờ xem trước riêng của nó. Đây là các tuyên bố năng lực về mã NextPDF: việc kiểm định FIPS 140-3 gắn với một module mật mã thông qua CMVP, mà trong triển khai này là HSM hoặc provider của người vận hành — NextPDF không phải là một module đã kiểm định, không nắm giữ chứng nhận nào, và không cấp chứng nhận nào.

Tuyên bốTiêu chuẩnĐiều khoản
Đăng nhập xác thực người dùng tới token trước các thao tác khóa riêng tư; PIN sai thì từ chối truy cập.PKCS#11 v3.1§5.6.8
Các khóa always-authenticate cần một phiên đăng nhập mới cho mỗi lần dùng; tái xác thực thất bại lặp lại có thể khóa PIN.PKCS#11 v3.1CKA_ALWAYS_AUTHENTICATE re-authentication
Một chữ ký ECDSA của token là phép ghép thô r‖s; bộ ký chuyển nó sang DER để tương tác PDF.PKCS#11 v3.1§6.3.1
Các tham số PSS ràng buộc hash, MGF, và độ dài salt; các bộ ký đặt salt bằng độ dài digest.PKCS#11 v3.1§6.1.9
Cổng FIPS từ chối tạo sinh chữ ký với RSA dưới 2048 bit hoặc bậc ECDSA dưới 224 bit.NIST SP 800-131A Rev.2§3 Table 2
Chuỗi context hậu lượng tử bị giới hạn ở 255 byte.FIPS 204HashML-DSA context handling
Việc kiểm định FIPS 140-3 gắn với các module mật mã thông qua CMVP.FIPS 140-3CMVP program scope

Mọi điều khoản đều được diễn giải; không có văn bản chuẩn tắc nào được tái hiện. NextPDF không đưa ra tuyên bố chứng nhận nào. Các bộ ký căn chỉnh hành vi của chúng với các điều khoản được trích dẫn như một năng lực. Việc một chữ ký được tạo ra có xác minh được hay không là quyết định của trình xác minh dựa trên các neo tin cậy của nó; an ninh khóa phụ thuộc vào token, HSM, và người vận hành — không phải chỉ riêng NextPDF.

  • Cơ chế truyền PIN tuân theo quy ước pin-source của URI PKCS#11 (RFC 7512); RFC đó nằm ngoài kho trích dẫn, nên hành vi ở trên được đúc kết từ mã nguồn sản phẩm, không phải một trích dẫn spec.

  • Xác nhận runtime đã nạp ext-pkcs11 trước khi khởi tạo Pkcs11Signer; việc khởi tạo thất bại nhanh khi extension vắng mặt. Bộ ký CLI cần bật proc_open và một binary openssl có provider hoặc engine PKCS#11 được cài đặt.

  • PIN, nhãn chứng thư, và nhãn khóa là #[SensitiveParameter], nên chúng bị loại khỏi các stack trace. Cấp PIN từ một trình quản lý bí mật; không bao giờ ghi nó vào mã nguồn, cấu hình đã commit vào kiểm soát phiên bản, hoặc log.

  • Khởi tạo là bước tốn kém trên cả hai bộ ký: đường PKCS#11 đăng nhập và đọc chứng thư, còn đường CLI thăm dò binary và backend. Hãy khởi tạo một lần và tái sử dụng thể hiện; cache module theo thư viện làm cho việc khởi tạo lặp lại đối với cùng một thư viện là an toàn.

  • Bọc một bộ ký trong HsmSignerProviderAdapter khi phía gọi làm việc qua SignerProviderInterface. Truyền id provider chuẩn tắc cho lớp được bọc — pkcs11-{module-id} hoặc openssl-cli — để các kiểm tra năng lực dùng đúng tập cho phép của backend.

  • Trước khi bật bản xem trước hậu lượng tử, hãy đối chiếu các định danh cơ chế của firmware token với các giá trị tạm thời mà NextPDF đăng ký; một sai lệch sẽ thất bại lúc ký. Không bật bản xem trước cho đầu ra PAdES sản xuất.

  • getResolvedBackend()getOpensslVersion() tồn tại để ghi lại bằng chứng; hãy lưu chúng cùng với bằng chứng ký khi chương trình tuân thủ của bạn yêu cầu tính tái lập.

Trang này chỉ tài liệu hóa 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 không gian tên nội bộ, các lớp trợ giúp, các bảng cơ chế, tên tệp runbook, và các tiền tố ticket đều nằm ngoài phạm vi.