KMS 공급자 계약
한눈에 보기
섹션 제목: “한눈에 보기”HsmSignerInterface는 제3자가 NextPDF에 키 보관을 제공하기 위해 구현하는 공개 계약입니다. 개인 키는 사용자 코드가 보유합니다. 엔진은 CMS 구조를 빌드합니다.
composer require nextpdf/core:^3개념 개요
섹션 제목: “개념 개요”NextPDF는 서명 조립과 키 보관을 분리합니다. 엔진은 바이트 범위를 준비하고 CMS SignedData 구조를 조립합니다. 엔진은 개인 키를 보유하지 않습니다. 키 보관은 공개 계약을 통해 서명 백엔드에 위임됩니다.
다음 세 가지 공개 계약 중 하나를 구현합니다.
SignerInterface. 기본 계약입니다. 주어진 데이터에 대한SignatureResult를 반환하고, 타임스탬프를 적용하며, 장기 검증 지원 여부를 보고합니다. 서명 로직이 프로세스 내에서 실행될 때 사용합니다.HsmSignerInterface. 키 보관 계약입니다. 구현체는 하드웨어 경계 내부에서 서명 작업을 수행해야 합니다. 개인 키는 그 경계를 벗어나면 안 됩니다. 키 관리 시스템 공급자가 이 계약을 구현합니다.DeferredSignerInterface. 비동기 백엔드를 위한SignerInterface의 확장입니다. 호출자가 데이터를 제출하고 작업 식별자를 받은 뒤, 나중에 결과를 검색합니다.
이 페이지는 공개 계약을 명시합니다. NextPDF Pro 또는 NextPDF Enterprise의 내부 구현은 설명하지 않습니다. 유료 에디션은 이 계약을 지원하는 구현을 제공할 수 있습니다. 구현체가 아니라 계약에 의존하십시오.
키 보관 요구 사항
섹션 제목: “키 보관 요구 사항”이 계약은 개인 키가 보안 경계를 절대 벗어나지 않도록 요구합니다. 표준 관행이 이 요구 사항을 뒷받침합니다. NIST SP 800-57 Part 1 Revision 5는 키 관리를 키의 전체 수명 주기에 걸친 키 처리로 정의합니다. 이 수명 주기는 안전한 생성, 저장, 배포, 사용 및 폐기입니다. PKCS#11 v3.1은 그 경계를 강제할 수 있게 합니다. 개인 키 객체에서 CKA_SENSITIVE를 true로 설정하거나 CKA_EXTRACTABLE을 false로 설정하면, 토큰은 토큰 외부에서 키 값을 평문으로 노출해서는 안 됩니다.
이 요구 사항을 준수할 책임은 사용자 구현에 있습니다. 엔진은 이를 대신 강제할 수 없습니다. 사용자 sign() 메서드가 원시 키 바이트를 프로세스 메모리로 읽어 들일 수 있다면, 이 계약의 보안 속성은 상실됩니다.
API 표면
섹션 제목: “API 표면”NextPDF\Contracts\HsmSignerInterface (stable, 1.0.0 이후):
| 메서드 | 반환값 | 용도 |
|---|---|---|
sign(string $data, string $algorithm) | string | 하드웨어 경계 내부에서 데이터에 서명합니다. 원시 서명 바이트를 반환합니다. 실패 시 RuntimeException을 던집니다. |
getCertificateDer() | string | 서명자 X.509 인증서를 DER 형식으로 반환합니다. |
getCertificateChainDer() | array<string> | 서명자 인증서를 제외하고, 발급자부터 루트까지의 중간 인증서를 반환합니다. |
getPublicKeyAlgorithm() | string | 공개 키 알고리즘 식별자를 반환합니다. |
NextPDF\Contracts\SignerInterface (stable, 1.0.0 이후):
| 메서드 | 반환값 | 용도 |
|---|---|---|
sign(string $data) | SignatureResult | DER로 인코딩된 CMS SignedData를 반환합니다. |
timestamp(string $signatureValue) | string | DER로 인코딩된 RFC 3161 타임스탬프 토큰을 반환합니다. |
supportsLtv() | bool | 장기 검증 데이터를 포함할 수 있는지 여부를 보고합니다. |
NextPDF\Contracts\DeferredSignerInterface (experimental, 3.0.0 이후)는 비동기 백엔드를 위해 SignerInterface를 submitForSigning(), retrieveSignature() 및 isComplete()로 확장합니다.
엔진이 생성하는 서명 레벨은 PAdES 프로파일을 따릅니다. ETSI EN 319 142-2는 EN 319 142-1의 기준 구성 요소를 기반으로 확장 PAdES 프로파일을 정의합니다. 엔진은 B-B, B-T, B-LT 및 B-LTA 레벨을 이러한 구성 요소에 매핑합니다. 사용자 서명자는 엔진이 필요로 하는 암호화 작업과 인증서 자료를 제공합니다.
코드 샘플 — 빠른 시작
섹션 제목: “코드 샘플 — 빠른 시작”다음은 최소한의 PKCS#11 스타일 공급자입니다. 서명 호출은 토큰에 위임됩니다. 키 값은 PHP로 절대 읽혀 들어오지 않습니다.
<?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'; }}코드 샘플 — 프로덕션
섹션 제목: “코드 샘플 — 프로덕션”프로덕션 공급자는 입력을 검증하고, 토큰 오류가 발생하면 닫힘 상태로 실패합니다. 키 또는 서명 자료는 절대 로깅하지 않습니다.
<?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); }}엣지 케이스 및 주의 사항
섹션 제목: “엣지 케이스 및 주의 사항”- 서명 바이트 형식. 원시 서명 바이트를 반환합니다. RSA의 경우 바이트는 DER입니다. ECDSA의 경우 바이트는 원시
r값 뒤에s값이 이어진 형태입니다. - 체인 순서.
getCertificateChainDer()는 서명자 인증서를 제외합니다. 중간 인증서를 발급자부터 루트까지 순서대로 정렬합니다. - 알고리즘 식별자.
sign()은 OpenSSL 스타일 식별자를 사용합니다.getPublicKeyAlgorithm()은 X.509 알고리즘 이름을 반환합니다. - 실패는 닫힘 상태로 처리됩니다. 토큰 또는 KMS 오류가 발생하면 항상
RuntimeException을 던집니다. 부분적이거나 빈 서명을 반환하지 마십시오. - 키 폐기. 키가 암호화 사용 기간의 끝에 도달하면, 키 관리 절차에 따라 키를 폐기합니다. NIST SP 800-57 Part 1 Revision 5 §8.2.1.2는 키가 더 이상 필요하지 않게 되는 즉시 폐기되어야 한다고 명시합니다. 폐기 절차 자체는 §8.3.4를 따릅니다.
데이터 레지던시 및 PII 완화
섹션 제목: “데이터 레지던시 및 PII 완화”이 계약은 서명할 데이터와 인증서 자료만 전송합니다. 문서 콘텐츠나 개인 데이터는 서명 백엔드로 전송하지 않습니다. 바이트 범위는 최소한으로 유지하십시오. 서명 사유 또는 위치 필드에 개인 데이터를 넣지 마십시오. 이러한 필드는 서명된 파일에서 관찰할 수 있습니다.
안전한 텔레메트리 및 로그 정리
섹션 제목: “안전한 텔레메트리 및 로그 정리”다음 항목은 절대 로깅하지 마십시오: sign()에 전달된 데이터, 반환된 서명 바이트, 복구 가능한 형태의 키 식별자 또는 인증서의 비공개 구성 요소. 작업 결과와 되돌릴 수 없는 참조만 로깅하십시오. SignatureAppliedEvent 후크는 지원되는 감사 앵커입니다. 액션 트리거를 참조하십시오.
위협 모델
섹션 제목: “위협 모델”| 자산 | 위협 | 완화 |
|---|---|---|
| 개인 키 | 프로세스 메모리로 유출 | 계약은 경계 내 서명을 요구합니다. PKCS#11 CKA_SENSITIVE / CKA_EXTRACTABLE 속성이 추출 불가능성을 강제합니다. |
| 서명 오라클 | 무제한 서명 요청 | 구현이 호출자를 인증하고 요청 속도를 제한합니다. |
| 인증서 체인 | 대체 | 구현은 신뢰할 수 있는 루트까지 빌드되는 체인을 반환합니다. |
| 서명 바이트 | 로그를 통한 노출 | 오류 경로는 닫힘 상태로 실패합니다. 텔레메트리에는 서명 자료를 남기지 않습니다. |
| 암호화 사용 기간이 지난 키 | 지속적인 사용 | NIST SP 800-57 Part 1 Revision 5 §8.2.1.2에 따른 키 폐기 |
적합성
섹션 제목: “적합성”서명 레벨은 PAdES 프로파일을 준수합니다. ETSI EN 319 142-2 §5.1은 EN 319 142-1 기준 구성 요소를 기반으로 확장 PAdES 프로파일을 정의합니다. 엔진은 사용자 서명자가 제공하는 자료를 바탕으로 이러한 구성 요소를 조립합니다. 키 관리는 NIST SP 800-57 Part 1 Revision 5 수명 주기(§8.2.1.2 폐기 요구 사항 포함)에 부합합니다. 하드웨어 키 보관은 PKCS#11 v3.1 추출 불가능 키 속성에 부합합니다. 인용 정보는 페이지 프런트매터에 기록되어 있습니다.
수출 통제 및 검토 거버넌스
섹션 제목: “수출 통제 및 검토 거버넌스”이 페이지는 PKCS#11 및 하드웨어 보안 모듈 키 보관을 다루므로, 프런트매터에서 export_control_class: legal-review-required를 설정합니다. 문서 검토 정책(plan §17 gate 6)에 따라, 보안 모드가 있거나 경로 또는 콘텐츠가 PAdES, FIPS, HSM 또는 PKCS#11과 일치하는 모든 페이지는 게시 전에 @nextpdf-labs/crypto-reviewers GitHub 팀의 승인을 받아야 합니다. 이 CODEOWNERS 승인은 필수 병합 게이트입니다. 페이지는 publish: false 상태를 유지하며, 법적 수출 통제 검토와 @nextpdf-labs/crypto-reviewers 검토가 모두 완료되어야 게시 보류가 해제됩니다.
상업적 맥락
섹션 제목: “상업적 맥락”NextPDF Enterprise는 키 관리 시스템 기반 키 보관, 인증서 체인 조립 및 감사 통합을 포함하여 이 계약을 지원하는 구현을 제공합니다. Core에서 HsmSignerInterface를 직접 구현하거나, 코드 변경 없이 동일한 공개 계약을 통해 Enterprise 구현을 사용합니다.
참고 항목
섹션 제목: “참고 항목”관련 계약 및 모듈
섹션 제목: “관련 계약 및 모듈”- 서명 계약 참조 —
SignerInterface,HsmSignerInterface,DeferredSignerInterface및 타임스탬프 공급자. - 보안 정책 계약 참조 — 인접한 보안 민감 SPI 표면.
- SPI 안정성 규칙 —
stable서명 계약의 기반이 되는 인터페이스 약속. - 액션 트리거 및 이벤트 리스너 — 지원되는 감사 앵커인
SignatureAppliedEvent. - 확장 작성 개요 — 전체 공개 SPI 표면.
용어집에서는 키 관리 시스템, 암호화 사용 기간 및 HSM을 정의합니다. 각 표준 정의는 게시된 용어집을 참조하십시오.