Bỏ qua để đến nội dung

Hợp đồng nhà cung cấp KMS

HsmSignerInterface là hợp đồng công khai để bên thứ ba triển khai việc lưu giữ khóa cho NextPDF. Nhà cung cấp của bạn chịu trách nhiệm lưu giữ khóa riêng tư. Engine lắp ráp cấu trúc Cryptographic Message Syntax (CMS).

Terminal window
composer require nextpdf/core:^3

NextPDF tách việc lắp ráp chữ ký khỏi việc lưu giữ khóa. Engine chuẩn bị dải byte và lắp ráp cấu trúc CMS SignedData. Nó không giữ khóa riêng tư. Thay vào đó, nó ủy thác việc lưu giữ khóa cho một back end ký qua hợp đồng công khai.

Bạn triển khai một trong ba hợp đồng công khai:

  • SignerInterface. Hợp đồng cơ sở. Nó trả về một SignatureResult cho dữ liệu được cung cấp, áp dụng dấu thời gian và báo cáo mức hỗ trợ xác thực dài hạn. Dùng hợp đồng này khi logic ký chạy trong tiến trình.
  • HsmSignerInterface. Hợp đồng lưu giữ khóa. Bản triển khai phải ký bên trong ranh giới phần cứng. Khóa riêng tư không được rời khỏi ranh giới đó. Nhà cung cấp hệ thống quản lý khóa triển khai hợp đồng này.
  • DeferredSignerInterface. Một phần mở rộng của SignerInterface dành cho các back end không đồng bộ. Bên gọi gửi dữ liệu, nhận về một định danh công việc rồi lấy kết quả sau đó.

Trang này đặc tả hợp đồng công khai. Nó không mô tả bất kỳ bản triển khai nội bộ nào của NextPDF Pro hay NextPDF Enterprise. Một phiên bản trả phí có thể cung cấp một bản triển khai được hỗ trợ của hợp đồng này. Bạn phụ thuộc vào hợp đồng, không phải vào bản triển khai.

Hợp đồng yêu cầu khóa riêng tư không bao giờ rời khỏi ranh giới an toàn. Các thông lệ quản lý khóa được công nhận ủng hộ yêu cầu này. National Institute of Standards and Technology (NIST) SP 800-57 Part 1 Revision 5 xem quản lý khóa là quá trình theo vòng đời để tạo, lưu trữ, phân phối, sử dụng và hủy khóa một cách an toàn. Public-Key Cryptography Standards #11 (PKCS#11) v3.1 giúp cưỡng chế ranh giới này. Khi một đối tượng khóa riêng tư đặt CKA_SENSITIVE thành true hoặc CKA_EXTRACTABLE thành false, token không được để lộ giá trị khóa dưới dạng văn bản thuần ra bên ngoài token.

Bản triển khai của bạn chịu trách nhiệm tuân thủ yêu cầu này. Engine không thể cưỡng chế yêu cầu đó thay bạn. Nếu phương thức sign() của bạn có thể đọc các byte khóa thô vào bộ nhớ tiến trình, thuộc tính bảo mật của hợp đồng sẽ không còn.

NextPDF\Contracts\HsmSignerInterface (ổn định, kể từ 1.0.0):

Phương thứcTrả vềMục đích
sign(string $data, string $algorithm)stringKý dữ liệu bên trong ranh giới phần cứng. Trả về các byte chữ ký thô. Ném RuntimeException khi thất bại.
getCertificateDer()stringTrả về chứng chỉ X.509 của bên ký dưới dạng Distinguished Encoding Rules (DER).
getCertificateChainDer()array<string>Trả về các chứng chỉ trung gian, từ bên cấp phát đến gốc, không bao gồm chứng chỉ của bên ký.
getPublicKeyAlgorithm()stringTrả về định danh thuật toán khóa công khai.

NextPDF\Contracts\SignerInterface (ổn định, kể từ 1.0.0):

Phương thứcTrả vềMục đích
sign(string $data)SignatureResultTrả về CMS SignedData được mã hóa DER.
timestamp(string $signatureValue)stringTrả về một token dấu thời gian Request for Comments (RFC) 3161 được mã hóa DER.
supportsLtv()boolCho biết dữ liệu xác thực dài hạn (LTV) có thể được nhúng hay không.

NextPDF\Contracts\DeferredSignerInterface (thử nghiệm, kể từ 3.0.0) mở rộng SignerInterface với submitForSigning(), retrieveSignature()isComplete() dành cho các back end không đồng bộ.

Các cấp độ chữ ký mà engine tạo ra tuân theo các hồ sơ PDF Advanced Electronic Signatures (PAdES). European Telecommunications Standards Institute (ETSI) EN 319 142-2 định nghĩa các hồ sơ PAdES mở rộng được xây dựng trên các khối nền tảng cơ sở trong EN 319 142-1. Engine ánh xạ các cấp độ B-B, B-T, B-LT và B-LTA tới các khối nền tảng đó. Bộ ký của bạn cung cấp phép toán mật mã và dữ liệu chứng chỉ mà engine cần.

Nhà cung cấp tối giản theo phong cách PKCS#11 này ủy thác thao tác ký cho token. PHP không bao giờ đọc giá trị khóa.

<?php
declare(strict_types=1);
use NextPDF\Contracts\HsmSignerInterface;
final class TokenSigner implements HsmSignerInterface
{
public function __construct(private readonly TokenSession $session) {}
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
{
// The token computes the signature. The key stays inside the token.
return $this->session->c_sign($data, $algorithm);
}
public function getCertificateDer(): string
{
return $this->session->readCertificate();
}
/** @return array<string> */
public function getCertificateChainDer(): array
{
return $this->session->readChain();
}
public function getPublicKeyAlgorithm(): string
{
return 'rsaEncryption';
}
}

Nhà cung cấp dùng trong sản xuất xác thực đầu vào, fail closed khi token gặp lỗi và không bao giờ ghi log phần khóa hay chữ ký.

<?php
declare(strict_types=1);
use NextPDF\Contracts\HsmSignerInterface;
use Psr\Log\LoggerInterface;
use RuntimeException;
final class KmsSigner implements HsmSignerInterface
{
public function __construct(
private readonly RemoteKmsClient $kms,
private readonly string $keyId,
private readonly LoggerInterface $logger,
) {}
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
{
if ($data === '') {
throw new RuntimeException('Refusing to sign empty data');
}
try {
// The KMS performs the operation. The key never reaches this process.
return $this->kms->sign($this->keyId, $data, $algorithm);
} catch (\Throwable $error) {
// Fail closed. Do not log key material or signature bytes.
$this->logger->error('kms.sign.failed', ['key' => $this->keyId]);
throw new RuntimeException('KMS signing failed', previous: $error);
}
}
public function getCertificateDer(): string
{
return $this->kms->certificate($this->keyId);
}
/** @return array<string> */
public function getCertificateChainDer(): array
{
return $this->kms->chain($this->keyId);
}
public function getPublicKeyAlgorithm(): string
{
return $this->kms->algorithm($this->keyId);
}
}
  • Định dạng byte chữ ký. Trả về các byte chữ ký thô. Với Rivest-Shamir-Adleman (RSA), các byte ở dạng DER. Với Elliptic Curve Digital Signature Algorithm (ECDSA), các byte là giá trị r thô theo sau bởi giá trị s.
  • Thứ tự chuỗi. getCertificateChainDer() không bao gồm chứng chỉ của bên ký. Sắp xếp các chứng chỉ trung gian từ bên cấp đến gốc.
  • Định danh thuật toán. sign() dùng các định danh theo phong cách OpenSSL. getPublicKeyAlgorithm() trả về tên thuật toán X.509.
  • Xử lý lỗi theo kiểu fail-closed. Ném RuntimeException khi token hoặc KMS gặp bất kỳ lỗi nào. Không trả về chữ ký một phần hoặc chữ ký rỗng.
  • Hủy khóa. Khi một khóa đạt đến cuối chu kỳ mật mã của nó, hãy hủy khóa theo quy trình quản lý khóa của bạn. NIST SP 800-57 Part 1 Revision 5 §8.2.1.2 nêu rằng khóa nên được hủy ngay khi không còn cần đến nữa. Bản thân việc hủy tuân theo §8.3.4.

Nơi lưu trữ dữ liệu và biện pháp giảm thiểu PII

Phần tiêu đề “Nơi lưu trữ dữ liệu và biện pháp giảm thiểu PII”

Hợp đồng chỉ chuyển dữ liệu cần ký và phần chứng chỉ. Nó không chuyển nội dung tài liệu hay dữ liệu cá nhân tới back end ký. Giữ dải byte ở mức tối thiểu. Không đặt dữ liệu cá nhân vào các trường lý do ký hoặc vị trí. Các trường đó vẫn có thể được quan sát trong tệp đã ký.

Không bao giờ ghi log dữ liệu được truyền vào sign(), các byte chữ ký được trả về, định danh khóa ở dạng có thể khôi phục, hay bất kỳ thành phần riêng tư nào của chứng chỉ. Chỉ ghi log kết quả thao tác và một tham chiếu không thể đảo ngược. Hook SignatureAppliedEvent là điểm neo kiểm toán được hỗ trợ. Xem Trình kích hoạt hành động.

Tài sảnMối đe dọaBiện pháp giảm thiểu
Khóa riêng tưRò rỉ vào bộ nhớ tiến trìnhHợp đồng yêu cầu ký bên trong ranh giới; PKCS#11 CKA_SENSITIVE / CKA_EXTRACTABLE cưỡng chế thuộc tính không thể trích xuất
Oracle kýYêu cầu ký không giới hạnBản triển khai giới hạn tốc độ và xác thực bên gọi
Chuỗi chứng chỉThay thếBản triển khai trả về một chuỗi dẫn đến một gốc tin cậy
Các byte chữ kýLộ thông tin qua logĐường xử lý lỗi fail-closed; không đưa phần chữ ký vào dữ liệu đo lường từ xa
Khóa đã hết chu kỳ mật mãTiếp tục sử dụngHủy khóa theo NIST SP 800-57 Part 1 Revision 5 §8.2.1.2

Các cấp độ chữ ký phù hợp với các hồ sơ PAdES. ETSI EN 319 142-2 §5.1 định nghĩa các hồ sơ PAdES mở rộng trên các khối nền tảng cơ sở EN 319 142-1. Engine lắp ráp các khối nền tảng đó từ dữ liệu mà bộ ký của bạn cung cấp. Việc quản lý khóa tuân theo vòng đời NIST SP 800-57 Part 1 Revision 5, bao gồm cả yêu cầu hủy ở §8.2.1.2. Việc lưu giữ khóa bằng phần cứng tuân theo các thuộc tính khóa không thể trích xuất của PKCS#11 v3.1. Các trích dẫn được ghi lại trong phần front matter của trang.

Kiểm soát xuất khẩu và quản trị rà soát

Phần tiêu đề “Kiểm soát xuất khẩu và quản trị rà soát”

Trang này đề cập đến việc lưu giữ khóa bằng PKCS#11 và mô-đun bảo mật phần cứng (HSM), nên front matter của trang đặt export_control_class: legal-review-required. Theo chính sách rà soát tài liệu (kế hoạch §17 cổng 6), bất kỳ trang nào có chế độ bảo mật, đường dẫn hoặc nội dung khớp với PAdES, FIPS, HSM hoặc PKCS#11 đều cần sự phê duyệt từ nhóm GitHub @nextpdf-labs/crypto-reviewers trước khi có thể xuất bản. Phê duyệt CODEOWNERS đó là cổng hợp nhất bắt buộc: trang vẫn giữ publish: false cho đến khi cả hai bước rà soát pháp lý về kiểm soát xuất khẩu và bước rà soát của @nextpdf-labs/crypto-reviewers hoàn tất.

NextPDF Enterprise cung cấp một bản triển khai được hỗ trợ của hợp đồng này với việc lưu giữ khóa bằng hệ thống quản lý khóa, lắp ráp chuỗi chứng chỉ và tích hợp kiểm toán. Bạn có thể tự triển khai HsmSignerInterface trong Core hoặc dùng bản triển khai Enterprise thông qua cùng hợp đồng công khai mà không cần thay đổi mã.

Bảng thuật ngữ định nghĩa key management system, cryptoperiodHSM; hãy xem bảng thuật ngữ đã xuất bản để biết định nghĩa chuẩn của từng mục.