Enterprise phiên bản
Ký HSM — Tài liệu tham chiếu chuyên sâu
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”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.
Tính khả dụng & cấp phép
Phần tiêu đề “Tính khả dụng & cấp phép”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.
Bề mặt API công khai
Phần tiêu đề “Bề mặt API công khai”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ệu | Tham số | Hành vi mặc định | Trả về | Ném hoặc thất bại với | Ghi chú |
|---|---|---|---|---|---|
Pkcs11Signer::__construct() | string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null | Mở 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ừ token | — | HsmOperationException khi thiếu ext-pkcs11 hoặc truy cập token thất bại | Mộ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-Value | string 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 enforcer | Tập thuật toán đóng; xem Hợp đồng hành vi |
Pkcs11Signer::signPqs() | string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true | Bị từ chối trừ khi $enablePostQuantum đã được đặt; điều phối cơ chế PQ PKCS#11 tạm thời | string 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ông | Báo cáo cờ opt-in của hàm khởi tạo | bool | Không | — |
Pkcs11Signer::getCertificateDer() | Không | Trả về chứng thư của bộ ký đọc từ token | string (DER) | Không | Được nạp một lần khi khởi tạo |
Pkcs11Signer::getCertificateChainDer() | Không | Trả về các chứng thư trung gian do hàm khởi tạo cung cấp | array<string> (DER) | Không | Loạ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 = null | Xá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 0600 | string 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 OpenSslCliSigner | Không | Kết quả khởi tạo chỉ đọc | string / array<string> / OpenSslCliBackend | Không | getCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion |
HsmSignerProviderAdapter::__construct() | HsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15 | Bọc một lớp HSM cụ thể thành một SignerProviderInterface | — | Không | Quy ước id provider: pkcs11-{module-id}, openssl-cli |
HsmSignerProviderAdapter::providerId() | Không | Trả về id do hàm khởi tạo cung cấp | non-empty-string | Khô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 backend | bool | Không | Từ 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ình | non-empty-string | KeyManagementException ($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'): stringpublic function signPqs(string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true): stringpublic function isPostQuantumEnabled(): boolpublic function getCertificateDer(): stringpublic function getCertificateChainDer(): arraypublic 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'): stringpublic function getCertificateDer(): stringpublic function getCertificateChainDer(): arraypublic function getPublicKeyAlgorithm(): stringpublic function getCertificatePem(): stringpublic function getResolvedBackend(): OpenSslCliBackendpublic function getOpensslVersion(): stringpublic function __construct(private HsmSignerInterface $hsm, private string $providerId, private SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15)public function providerId(): stringpublic function supportsAlgorithm(SignatureAlgorithm $algo): boolpublic function sign(string $data, ?string $keyVersion = null): stringHợp đồng hành vi
Phần tiêu đề “Hợp đồng hành vi”- 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;OpenSslCliSignertruyền một tham chiếu khóa — một URI PKCS#11 — cho tiến trình conopenssl. Không bộ ký nào có thể xuất khóa. - Phiên và đăng nhập.
Pkcs11Signercache 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.Pkcs11Signerchấp nhận thêmecdsa-raw. Bất kỳ định danh nào khác đều làm phát sinhInvalidArgumentException— 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 r và s (PKCS#11 v3.1 §6.3.1).
Pkcs11Signer::sign()chuyển đầu ra đó sang dạngECDSA-Sig-Valuemã 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-sourcecủ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ạngpin-valuetrong 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.
OpenSslCliSignersinh 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ỳ$keyVersionkhác null nào vớiKeyManagementExceptionthay 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 sinhSignatureFailedException. - Xem trước hậu lượng tử.
signPqs()bị chắn sau cờ khởi tạo$enablePostQuantumvà 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.
Trường hợp biên & chế độ lỗi
Phần tiêu đề “Trường hợp biên & chế độ lỗi”- Khởi tạo
Pkcs11Signermà không cóext-pkcs11làm phát sinhHsmOperationExceptionngay 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
HsmOperationExceptionnê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).
OpenSslCliSignertừ chối một$keyUriđã chứa sẵnpin-valuelú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
HsmOperationExceptionthay vì hoãn lỗi tới lúc ký. - Một tiến trình con vượt quá
$timeoutSecondsbị 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.
HsmSignerProviderAdaptervới id provideropenssl-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ý.
Hành vi ở chế độ FIPS
Phần tiêu đề “Hành vi ở chế độ FIPS”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.
Tuân thủ
Phần tiêu đề “Tuân thủ”| 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.1 | CKA_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 204 | HashML-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-3 | CMVP 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.
Ghi chú phát triển
Phần tiêu đề “Ghi chú phát triển”-
Cơ chế truyền PIN tuân theo quy ước
pin-sourcecủ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-pkcs11trước khi khởi tạoPkcs11Signer; việc khởi tạo thất bại nhanh khi extension vắng mặt. Bộ ký CLI cần bậtproc_openvà một binaryopensslcó 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
HsmSignerProviderAdapterkhi phía gọi làm việc quaSignerProviderInterface. Truyền id provider chuẩn tắc cho lớp được bọc —pkcs11-{module-id}hoặcopenssl-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()và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.
Xem thêm
Phần tiêu đề “Xem thêm”- Ký bằng module bảo mật phần cứng (PKCS#11) — trang năng lực với các bước thiết lập, cấu hình, và xác minh.
- Bảo mật — tài liệu tham chiếu chuyên sâu — bề mặt bảo mật Enterprise hợp nhất.
- Chữ ký — tài liệu tham chiếu chuyên sâu — bộ tạo sinh dài hạn PAdES B-LT / B-LTA.
- FIPS 140 — tài liệu tham chiếu chuyên sâu — chính sách mật mã, bộ tự kiểm, và cổng
FipsSignatureEnforcer. - Xem trước PQC — tài liệu tham chiếu chuyên sâu — bề mặt xem trước hậu lượng tử và các ranh giới của nó.
- Bảo mật / Ký (Core) — bộ ký CMS của Core và các hợp đồng ký.
Ranh giới xuất bản
Phần tiêu đề “Ranh giới xuất bản”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.