PDFium Delphi Component Docs

FPdfCrypto 유닛

유닛: FPdfCrypto
플랫폼 백엔드, PKCS#11 통합, 신뢰 저장소, 폐기 fetcher, 한도 있는 경로 검증을 위한 PAdES 서명자 공급자 및 인증서 검증 파사드입니다

구문

TPadesPaddingScheme = (psRsaPss, psRsaPkcs1v15, psEcdsa);

TPadesSignerOptions = record
  CertificateThumbprint: string;
  PaddingScheme: TPadesPaddingScheme;
  class function Default: TPadesSignerOptions; static;
end;

TPadesChainCertArray = array of TBytes;

TPadesResolvedSigner = record
  Signer: ICmsSigner;
  SignerCertDer: TBytes;
  ChainCertDer: TPadesChainCertArray;
end;

TPdfRevocationMode = (prmNone, prmOffline, prmOnlineAllowed,
  prmOnlineRequired);
TPdfStringArray = array of string;

TPdfCertificatePathOptions = record
  ValidationTime: TDateTime;
  RevocationMode: TPdfRevocationMode;
  RequiredPolicyOids: TPdfStringArray;
  MaxCertificates: Integer;
  MaxCertificateBytes: Integer;
  MaxFetchBytes: Integer;
  MaxPathDepth: Integer;
  class function Default: TPdfCertificatePathOptions; static;
end;

TPdfCertificatePathReport = record
  Trusted: Boolean;
  PathBuilt: Boolean;
  PolicyValid: Boolean;
  RevocationChecked: Boolean;
  PathCertificateCount: Integer;
  ErrorCode: Integer;
  ErrorMessage: string;
end;

IPdfTrustStore = interface
  function LoadTrustAnchors: TPadesChainCertArray;
end;

IPdfValidationFetcher = interface
  function Fetch(const Uri: string; MaxBytes: Integer;
    out Data: TBytes): Boolean;
end;

IPdfCertificatePathValidator = interface
  function Validate(const LeafCertificate: TBytes;
    const Intermediates, TrustAnchors: TPadesChainCertArray;
    TrustStore: IPdfTrustStore; Fetcher: IPdfValidationFetcher;
    const Options: TPdfCertificatePathOptions;
    out Report: TPdfCertificatePathReport): Boolean;
end;

IPadesSignerProvider = interface
  function BackendName: string;
  function Resolve(const Options: TPadesSignerOptions): TPadesResolvedSigner;
end;

TPdfPkcs11Slot = record
  SlotID: UInt64;
  Description: string;
  TokenLabel: string;
  TokenPresent: Boolean;
end;
TPdfPkcs11Slots = array of TPdfPkcs11Slot;

TPdfPkcs11Certificate = record
  SlotID: UInt64;
  ObjectID: TBytes;
  LabelText: string;
  CertificateDer: TBytes;
  Mechanisms: TPdfStringArray;
end;
TPdfPkcs11Certificates = array of TPdfPkcs11Certificate;

IPdfPkcs11SignerProvider = interface(IPadesSignerProvider)
  function EnumerateSlots: TPdfPkcs11Slots;
  function EnumerateCertificates(SlotID: UInt64): TPdfPkcs11Certificates;
  procedure CloseProtectedSessions;
end;

TPdfCmsVerifyStatus = (pcvsUnavailable, pcvsValid, pcvsInvalid,
  pcvsUnsupported, pcvsIndeterminate);
TPdfCmsRevocationReason = (pcrrNone, pcrrCertificateRevoked, pcrrCrlExpired,
  pcrrCrlNotYetValid, pcrrCrlUnavailable, pcrrCrlSignatureInvalid,
  pcrrCrlInvalid, pcrrChainUntrusted, pcrrUnknown, pcrrOcspUnavailable,
  pcrrOcspInvalid, pcrrOcspStatusUnknown);
TPdfCmsVerifyStage = (pcvstCryptographicSignature, pcvstChainBuild,
  pcvstOnlineRetrieval, pcvstRevocationCheck);
TPdfCmsVerifyCheckpoint = procedure(Stage: TPdfCmsVerifyStage) of object;

TPdfCmsVerifyOptions = record
  OnlineRetrieval: Boolean;
  CheckRevocation: Boolean;
  CollectChainCertificates: Boolean;
  UrlRetrievalTimeoutMs: Cardinal;
  OnCheckpoint: TPdfCmsVerifyCheckpoint;
  CollectSignerDiagnostics: Boolean;
  MaxSignerCount: Integer;
  class function Default: TPdfCmsVerifyOptions; static;
end;

TPdfCmsSignerVerifyResult = record
  SignerIndex: Integer;
  SignatureStatus, TrustStatus, RevocationStatus: TPdfCmsVerifyStatus;
  SignatureError, TrustError: Cardinal;
  SignerCertificate: TBytes;
  RevocationReason: TPdfCmsRevocationReason;
  RevocationError: Cardinal;
  RevocationCertificate: TBytes;
end;
TPdfCmsSignerVerifyResults = array of TPdfCmsSignerVerifyResult;

TPdfCmsVerifyResult = record
  SignatureStatus: TPdfCmsVerifyStatus;
  TrustStatus: TPdfCmsVerifyStatus;
  RevocationStatus: TPdfCmsVerifyStatus;
  SignatureError: Cardinal;
  TrustError: Cardinal;
  SignerCertificate: TBytes;
  ChainCertificates: TPadesChainCertArray;
  RevocationReason: TPdfCmsRevocationReason;
  RevocationError: Cardinal;
  RevocationCertificate: TBytes;
  SignerResults: TPdfCmsSignerVerifyResults;
  SignerDiagnosticsStatus: TPdfCmsVerifyStatus;
  SignerCount: Integer;
end;

IPdfCmsVerifier = interface
  function BackendName: string;
  function VerifyDetached(const CmsDer: TBytes;
    Segment1: Pointer; Segment1Length: Cardinal;
    Segment2: Pointer; Segment2Length: Cardinal;
    const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
  function VerifyAttached(const CmsDer: TBytes;
    const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
end;

procedure ConfigurePadesCmsVerifier(const Verifier: IPdfCmsVerifier);
function PadesCmsVerificationAvailable: Boolean;
function PadesCmsVerificationBackendName: string;
function PadesCryptoAvailable: Boolean;
function PadesCryptoBackendName: string;
function ResolvePadesSigner(const Options: TPadesSignerOptions): TPadesResolvedSigner;
procedure ConfigurePdfCertificatePathValidator(
  const Validator: IPdfCertificatePathValidator);
function ValidatePdfCertificatePath(const LeafCertificate: TBytes;
  const Intermediates, TrustAnchors: TPadesChainCertArray;
  TrustStore: IPdfTrustStore; Fetcher: IPdfValidationFetcher;
  const Options: TPdfCertificatePathOptions;
  out Report: TPdfCertificatePathReport): Boolean;
procedure ConfigurePadesSignerProvider(const Provider: IPadesSignerProvider);

TPadesSignerResolverProc = function(const Options: TPadesSignerOptions): TPadesResolvedSigner;

PadesSignerResolverOverride: TPadesSignerResolverProc;
PdfCertificatePathValidator: IPdfCertificatePathValidator;
PadesSignerProvider: IPadesSignerProvider;
PadesCmsVerifier: IPdfCmsVerifier;

설명

FPdfCrypto는 PAdES 서명 스택의 진입점입니다. PadesCryptoAvailable은 서명 재료와 백엔드의 이용 가능성을 보고하고 PadesCryptoBackendName은 선택한 백엔드를 나타냅니다. Windows는 기본적으로 Cryptography Next Generation을 사용하며 다른 플랫폼은 FPdfCryptoSsl에 명시적으로 설정한 OpenSSL 개인키와 인증서를 해석합니다

ResolvePadesSigner는 인증서 썸프린트와 패딩 방식을 받아 완전히 채워진 TPadesResolvedSigner를 반환합니다. 여기에는 개인 키 연산을 수행하는 ICmsSigner 구현, 서명자 인증서 DER, 발급 체인 인증서가 포함됩니다. 결과는 FPdfCms.BuildSignedData로 곧바로 전달됩니다

사용자 지정 통합은 토큰 슬롯과 인증서를 열거하는 IPdfPkcs11SignerProvider를 포함한 IPadesSignerProvider를 등록하거나, 결정론적 해석자 이음새로 PadesSignerResolverOverride를 사용할 수 있습니다

인증서 경로 검증은 공급자 기반이며 예산이 적용됩니다. 호출자는 IPdfCertificatePathValidator를 구성하고 선택적으로 명시적 신뢰 앵커, IPdfTrustStore, IPdfValidationFetcher를 제공한 뒤 TPdfCertificatePathReport를 점검합니다

함수

함수설명
PadesCryptoAvailable현재 플랫폼에서 PAdES 서명에 사용할 크립토 백엔드가 있으면 True를 반환합니다
PadesCryptoBackendName활성 크립토 백엔드의 표시 이름을 반환합니다
ResolvePadesSigner인증서 썸프린트와 패딩 방식을 서명자, 서명자 인증서, 체인으로 해석합니다
ConfigurePdfCertificatePathValidatorValidatePdfCertificatePath가 사용하는 프로세스 전체 IPdfCertificatePathValidator를 설정하거나 지웁니다
ValidatePdfCertificatePath인증서 수, 크기, fetch, 경로 깊이 예산을 강제한 뒤 리프 인증서를 중간 인증서 및 결합된 명시적·신뢰 저장소 앵커와 대조해 검증합니다
ConfigurePadesSignerProvider플랫폼 백엔드보다 먼저 사용되는 프로세스 전체 서명자 공급자를 설정하거나 지웁니다
ConfigurePadesCmsVerifierPAdES 검증기가 사용할 CMS 검증 백엔드를 등록합니다. 설정을 지우면 Windows에서 Windows CryptoAPI로 돌아갑니다. 다른 플랫폼은 ConfigureSslCmsVerifier나 ConfigureKeychainCmsVerifier를 명시적으로 호출해야 합니다
PadesCmsVerificationAvailable등록되었든 내장이든 이 빌드에서 CMS를 검증할 수 있는 백엔드가 있으면 True를 반환합니다
PadesCmsVerificationBackendName활성 검증 백엔드의 표시 이름을 반환하고 없으면 빈 문자열을 반환합니다

프로바이더 인터페이스

인터페이스 멤버설명
IPdfTrustStore.LoadTrustAnchors구성된 인증서 예산의 적용을 받아 추가 DER 인코딩 신뢰 앵커를 반환합니다
IPdfValidationFetcher.FetchMaxBytes를 초과하지 않으면서 Uri에서 검증 자료를 가져옵니다
IPdfCertificatePathValidator.Validate인증서 경로를 만들고 평가하며 TPdfCertificatePathReport를 채웁니다
IPadesSignerProvider.BackendNamePadesCryptoBackendName이 노출하는 공급자 표시 이름을 반환합니다
IPadesSignerProvider.Resolve전달된 TPadesSignerOptions에 대해 완전한 서명자 자료를 반환합니다
IPdfPkcs11SignerProvider.EnumerateSlots사용 가능한 PKCS#11 슬롯과 토큰 존재 메타데이터를 반환합니다
IPdfPkcs11SignerProvider.EnumerateCertificatesPKCS#11 슬롯 하나에서 보이는 인증서와 서명 메커니즘을 반환합니다
IPdfPkcs11SignerProvider.CloseProtectedSessions공급자가 소유한 보호되거나 인증된 PKCS#11 세션을 닫습니다
IPdfCmsVerifier.BackendNamePadesCmsVerificationBackendName이 보고하는 검증 백엔드 표시 이름을 반환합니다
IPdfCmsVerifier.VerifyDetachedPDF 서명을 검증합니다. 서명 대상 콘텐츠는 /Contents 구멍 양옆의 두 바이트 범위입니다
IPdfCmsVerifier.VerifyAttached타임스탬프 토큰을 검증합니다. 토큰은 자체 콘텐츠를 담고 있어 detached 세그먼트가 필요 없습니다

타입

타입설명
EPadesCrypto크립토 백엔드 실패에 대한 기본 예외
EPadesCryptoUnavailable필요한 서명자 백엔드나 인증서 경로 검증기가 구성되지 않았을 때 발생합니다
TPadesPaddingSchemepsRsaPss, psRsaPkcs1v15, psEcdsa
TPadesSignerOptionsCertificateThumbprint가 인증서를 선택하고 PaddingScheme이 서명 방식을 선택합니다; Default는 빈 썸프린트와 psRsaPss를 사용합니다
TPadesChainCertArrayDER로 인코딩된 체인 인증서의 동적 배열
TPadesResolvedSignerSigner, SignerCertDer, ChainCertDer가 해석된 서명자와 인증서 자료를 묶습니다
TPdfRevocationModeprmNone, prmOffline, prmOnlineAllowed, prmOnlineRequired
TPdfStringArray정책 OID와 공급자 메커니즘 이름에 사용되는 동적 문자열 배열
TPdfCertificatePathOptionsValidationTime, RevocationMode, RequiredPolicyOids, MaxCertificates, MaxCertificateBytes, MaxFetchBytes, MaxPathDepth가 검증과 리소스 예산을 제어합니다; Default는 오프라인 폐기 검사와 함께 인증서 64개, 인증서당 4 MiB, 가져온 데이터 16 MiB, 경로 깊이 16 한도를 선택합니다
TPdfCertificatePathReportTrusted, PathBuilt, PolicyValid, RevocationChecked, PathCertificateCount, ErrorCode, ErrorMessage가 검증 결과를 보고합니다
TPdfPkcs11SlotSlotID, Description, TokenLabel, TokenPresent가 PKCS#11 슬롯 하나를 설명합니다
TPdfPkcs11SlotsTPdfPkcs11Slot 레코드의 동적 배열
TPdfPkcs11CertificateSlotID, ObjectID, LabelText, CertificateDer, Mechanisms가 토큰 인증서 하나를 설명합니다
TPdfPkcs11CertificatesTPdfPkcs11Certificate 레코드의 동적 배열
TPadesSignerResolverProcPadesSignerResolverOverride 주입 var을 위한 함수 포인터 형식
TPdfCmsVerifyStatuspcvsUnavailable, pcvsValid, pcvsInvalid, pcvsUnsupported, pcvsIndeterminate
TPdfCmsRevocationReasonpcrrNone, pcrrCertificateRevoked, pcrrCrlExpired, pcrrCrlNotYetValid, pcrrCrlUnavailable, pcrrCrlSignatureInvalid, pcrrCrlInvalid, pcrrChainUntrusted, pcrrUnknown, pcrrOcspUnavailable, pcrrOcspInvalid, pcrrOcspStatusUnknown은 검증 상태와 별도로 폐지 증거를 설명합니다
TPdfCmsVerifyStagepcvstCryptographicSignature, pcvstChainBuild, pcvstOnlineRetrieval, pcvstRevocationCheck
TPdfCmsVerifyCheckpoint검증이 진행되면서 각 TPdfCmsVerifyStage를 받는 객체 메서드 콜백
TPdfCmsVerifyOptionsOnlineRetrieval, CheckRevocation, CollectChainCertificates, UrlRetrievalTimeoutMs, OnCheckpoint로 검증을 제어합니다. CollectSignerDiagnostics는 서명자별 스냅샷을 요청하고 MaxSignerCount는 개수를 제한합니다. Default는 조회, 폐지 검사, 서명자 진단을 끄고 조회 시간을 15초, 서명자 스냅샷을 64개로 제한합니다
TPdfCmsSignerVerifyResultSignerIndex는 인코딩한 SignerInfo 순서를 나타냅니다. 서명, 신뢰, 폐지 상태와 네이티브 오류는 해당 서명자를 독립적으로 설명합니다. SignerCertificate는 서명자의 DER 인증서이며 RevocationCertificate는 백엔드가 제공할 수 있을 때 수집한 폐지 오류의 관련 인증서입니다
TPdfCmsSignerVerifyResults상한이 있는 서명자 스냅샷의 동적 배열
TPdfCmsVerifyResult집계한 서명, 신뢰, 폐지 상태도 독립적입니다. 레코드는 SignatureError, TrustError, SignerCertificate, ChainCertificates, RevocationReason, RevocationError, RevocationCertificate, SignerResults, SignerDiagnosticsStatus, SignerCount도 반환합니다

인증서 폐기 진단

공개 옵션 및 결과 레코드가 커졌으므로 업그레이드 시 사용 코드를 다시 빌드하세요. 사용자 검증기는 관리형 결과를 Default(TPdfCmsVerifyResult)로 초기화하고 지원하지 않는 스냅샷 필드는 unavailable로 두어야 합니다. 문자열이나 동적 배열을 가진 살아 있는 레코드를 FillChar로 지우지 마세요

IPdfCmsVerifier.VerifyDetached나 VerifyAttached가 반환하는 TPdfCmsVerifyResult에서 RevocationReason과 RevocationError를 읽습니다. PAdES trust 검증은 이를 RevocationReason과 NativeRevocationError로 보존하고, timestamp 토큰용으로는 별도의 TimeStampRevocationReason과 NativeTimeStampRevocationError 필드를 둡니다. evidence 리포트에는 두 쌍이 모두 들어갑니다

RevocationError는 백엔드별 네이티브 검증 코드이며 0은 잡아낸 네이티브 진단이 없다는 뜻입니다. OpenSSL은 X509_V_ERR_* 오류 공간을 씁니다. Windows는 인증서의 CERT_REVOCATION_INFO.dwRevocationResult에서 나온 raw DWORD를, 폐기 체인 호출이 실패하면 GetLastError 값을 그대로 유지합니다. 이는 균일한 HRESULT 오류 공간도, 집합 체인 신뢰 비트마스크도 아닙니다

OpenSSL은 확인된 폐지와 만료/사용 불가/잘못된 CRL, 사용 불가/잘못된/unknown OCSP를 구분합니다. Windows는 확인된 폐지, 신뢰하지 않는 체인, 알 수 없는 네이티브 실패를 보고합니다. macOS 검증기는 서명 무결성, Basic X.509 신뢰, 폐지를 따로 평가하고 모든 플랫폼 오류를 CRL/OCSP 분류로 바꾸지 않고 Security.framework 오류를 반환합니다

RevocationCertificate는 CMS 서명자 대신 폐지된 중간 인증서일 수도 있으며 수집할 수 없는 백엔드에서는 비어 있습니다. OpenSSL은 수집할 수 있지만 현재 macOS 백엔드는 비워 둡니다

pcrrNone도 0 오류도 폐기 검사가 수행되었거나 성공했다는 증거가 아닙니다. 항상 RevocationStatus를 확인하세요

서명자별 진단

CollectSignerDiagnostics=True로 설정하면 SignerResults에서 상한이 있는 스냅샷을 볼 수 있습니다. SignerCount는 확인된 인코딩 SignerInfo 수이며 0은 수를 확인하지 못했다는 뜻입니다

SignerDiagnosticsStatus=pcvsValid는 유효하지 않은 서명의 스냅샷까지 포함해 요청한 수집이 끝났다는 뜻이며 모든 서명이 통과했다는 뜻은 아닙니다. pcvsUnavailable은 수집을 끄거나 지원하지 않는 경우이고 pcvsIndeterminate는 파싱 또는 리소스 상한 안에서 요청한 수집을 끝내지 못한 경우입니다

OpenSSL과 네이티브 macOS는 최대 64서명자를 수집합니다. OpenSSL은 진단 CMS 입력 4 MiB와 진단 입출력 작업 합계 64 MiB도 제한합니다. macOS 반환 인증서는 각 4 MiB, 합계 64 MiB이며 더 낮은 MaxSignerCount로 요청 개수를 줄일 수 있습니다

서명자 스냅샷은 설정한 증거와 집계 검증 중 가져온 증거를 재사용합니다. OpenSSL은 진단마다 다시 네트워크 조회를 하지 않으며 불완전한 집계 조회가 성공한 오프라인 폐지 스냅샷으로 바뀌지도 않습니다

기본 서명 백엔드

PadesSignerResolverOverride를 우선하고 다음으로 명시 등록한 IPadesSignerProvider, 마지막으로 플랫폼 기본값을 사용합니다. Windows 이외 기본값은 ConfigureSslSigningCredentials가 필요하며 libcrypto만으로 개인키나 인증서가 제공되지는 않습니다

OpenSSL 기본값은 명시 설정으로 인증서를 선택했으므로 비어 있지 않은 CertificateThumbprint를 거부합니다. 애플리케이션이 Keychain 프로바이더를 선택하면 ConfigureKeychainSignerProvider로 계속 사용할 수 있습니다

전역 프로바이더 변수

변수설명
PadesSignerResolverOverride등록된 공급자와 플랫폼 공급자보다 먼저 평가되는 선택적 해석자 콜백
PadesCmsVerifier현재 CMS 검증 백엔드이며 보통 ConfigurePadesCmsVerifier로 할당됩니다
PdfCertificatePathValidator현재 인증서 경로 검증기이며 보통 ConfigurePdfCertificatePathValidator로 할당됩니다
PadesSignerProvider현재 서명자 공급자이며 보통 ConfigurePadesSignerProvider로 할당됩니다

관련 항목

FPdfCms, FPdfCryptoWin, FPdfCryptoSsl, FPdfCryptoMac, FPdfCryptoOcsp, FPdfTsa, TPdf.SignPades