TPDFlibPKCS11Client

安全性與簽章

描述

在執行階段載入廠商的 PKCS #11 模組,並公開未向 Windows CSP 或 KSP 提供者註冊的憑證與私密金鑰用戶端會列舉存在的權杖、開啟持續性工作階段、驗證使用者、以二進位

CKA_ID 配對 X.509 憑證與簽署金鑰,並透過 CKM_RSA_PKCS 或 CKM_ECDSA 簽署已計算的摘要明確的憑證選用探索可以依標籤或二進位 ID 選取 ML-DSA 私密金鑰、驗證其

CKA_PARAMETER_SETCKM_ML_DSA

SignDigest,並透過 TPDFlibExternalDigestSignEvent 簽署原始訊息TPDFlib.OnExternalDigestSign 實作

單位

PDFlibPKCS11

建構與模組生命週期

Constructor TPDFlibPKCS11Client.Create;
Destructor TPDFlibPKCS11Client.Destroy;
Function TPDFlibPKCS11Client.LoadModule: Boolean;
Procedure TPDFlibPKCS11Client.UnloadModule;
Function TPDFlibPKCS11Client.UseFunctionList(FunctionList: PPLPKCS11FunctionList; AlreadyInitialized: Boolean): Boolean;

ModulePath 識別匯出 C_GetFunctionList 的 Win32 或 Win64 PKCS #11 DLL使用相同路徑的用戶端共用一個已載入模組與一個平衡的

C_Initialize/C_Finalize 生命週期載入器會先要求

CKF_OS_LOCKING_OK

UseFunctionList;無法提供內部鎖定的模組會受到共用呼叫鎖定保護,而符合規範的模組則允許個別的用戶端工作階段並行執行UnloadModule 支援靜態連結、內嵌或應用程式管理的提供者;呼叫端必須讓提供的表格保持存活,直到

權杖探索與連接

Function TPDFlibPKCS11Client.RefreshTokens: Boolean;
Function TPDFlibPKCS11Client.GetToken(Index: Integer; Out Token: TPDFlibPKCS11Token): Boolean;
Function TPDFlibPKCS11Client.Connect: Boolean;
Procedure TPDFlibPKCS11Client.Disconnect;
Function TPDFlibPKCS11Client.GetSelectedToken(Out Token: TPDFlibPKCS11Token): Boolean;
Property TPDFlibPKCS11Client.TokenCount: Integer;

RefreshTokens 會在熱插拔事件改變數量時以有界限的重試列舉存在的插槽,TokenCount 則回報上次重新整理找到的權杖數量使用

SlotID、TokenLabel、TokenSerial 或其組合選取權杖;空選項只有在恰好存在一個權杖時才會成功

TPDFlibPKCS11Token 回報插槽描述、製造商、權杖標籤、型號、序號、旗標與 PIN 長度界限

參數

CertificateLabelX.509 憑證物件的選用 UTF-8 CKA_LABEL 篩選器
CertificateID選用的二進位 CKA_ID 篩選器,儲存在 AnsiString 中
PrivateKeyLabel私密簽署金鑰的選用 UTF-8 CKA_LABEL 篩選器
PrivateKeyID選用的二進位私密金鑰 CKA_ID;空白時會重複使用憑證 ID
CertificateOptional預設為 False;為 True 時需要私密金鑰標籤或 ID,且探索只接受沒有 X.509 憑證的 ML-DSA 金鑰

CKA_SIGN=True

MLDSAParameterSet

CertificateDER、驗證憑證 DER,並拒絕 RSA/EC 類型不符;憑證選用探索需要一個無歧義的 ML-DSA 金鑰,並驗證參數集 44、65 或 87解析後的 ML-DSA 參數集透過 ResolvedPrivateKeyID 公開解析後的憑證透過

驗證

UserPIN僅寫入的使用者 PIN,以 UTF-8 編碼,會對權杖界限進行檢查,並在取代或終結時清除
UseProtectedAuthenticationPath當權杖宣告 CKF_PROTECTED_AUTHENTICATION_PATH 時傳遞 null PIN
ReadWriteSession加入 CKF_RW_SESSION;簽署通常只需要預設的唯讀序列工作階段

具有 CKA_ALWAYS_AUTHENTICATE=True 的金鑰會在每次成功的 C_SignInit 之後接收內容特定的登入

ClearPIN 會覆寫並釋放已設定的 PIN

簽署

Function TPDFlibPKCS11Client.SupportsMechanism(MechanismType: Cardinal): Boolean;
Function TPDFlibPKCS11Client.SupportsAlgorithm(DigestAlgorithm, SignatureAlgorithm: Integer): Boolean;
Function TPDFlibPKCS11Client.SignMLDSA(Const Message: AnsiString; Out Signature: AnsiString): Boolean;
Function TPDFlibPKCS11Client.SignHash(Const Digest: AnsiString; DigestAlgorithm, SignatureAlgorithm: Integer; Out Signature: AnsiString): Boolean;
Function TPDFlibPKCS11Client.SignDigest(Sender: TObject; SignProcessID: Integer; Const Digest: AnsiString; DigestAlgorithm, SignatureAlgorithm: Integer; Var Signature: AnsiString): Boolean;

RSA 簽章使用原始 CKM_RSA_PKCS 搭配本地建構的 DER DigestInfo,權杖因此不會把 PDF 摘要再雜湊一次

ECDSA 簽章使用原始 CKM_ECDSA;權杖的 P1363 輸出在 PDF_EXTERNAL_SIGNATURE_ECDSA_P1363 下原樣傳回,在 PDF_EXTERNAL_SIGNATURE_ECDSA_DER 下轉為嚴格 DER

SignMLDSA 把原始訊息交給帶空機制參數的單部分 CKM_ML_DSA,選用預設的空 context;它獨立於 SignHash 與 CMS 摘要回呼

SHA-1、SHA-256、SHA-384、SHA-512、SHA3-256、SHA3-384 與 SHA3-512 的摘要長度會在任何私鑰操作前驗證

只有 C_SignInit 在簽署開始前失敗時,才會重新開啟並重試遺失的 session,避免 C_Sign 失敗結果不明時重複執行私鑰操作

範例

var
  Token: TPDFlibPKCS11Client;
  ProcessID: Integer;
begin
  Token:= TPDFlibPKCS11Client.Create;
  try
    Token.ModulePath:= 'C:\Program Files\Vendor\pkcs11.dll';
    Token.TokenLabel:= 'Signing token';
    Token.CertificateLabel:= 'Document signer';
    Token.UserPIN:= UserPIN;
    if not Token.Connect then
      raise Exception.Create(String(Token.LastError));

    PDF.OnExternalDigestSign:= Token.SignDigest;
    ProcessID:= PDF.NewSignProcessFromFile(InputFile, '');
    PDF.SetSignProcessField(ProcessID, 'Approval');
    PDF.SetSignProcessDigestAlgorithm(ProcessID, 2);
    PDF.SetSignProcessExternalDigestSigner(ProcessID,
      Token.CertificateDER, PDF_EXTERNAL_SIGNATURE_RSA_PKCS1, 512);
    PDF.EndSignProcessToFile(ProcessID, OutputFile);
  finally
    Token.Free;
  end;
end;

狀態與失敗行為

Connected、KeyType、MLDSAParameterSet、AlwaysAuthenticate、FunctionListMajor 與 FunctionListMinor 公開現用的提供者狀態當模組載入、權杖選取、驗證、物件探索、屬性界限、機制檢查或簽署失敗時,方法會傳回

False 並同時設定 LastReturnValue 與 LastError

另請參閱

OnExternalDigestSign, SetSignProcessExternalDigestSigner, SetSignProcessDigestAlgorithm, TPDFlibCSCClient

PIN 管理

Function TPDFlibPKCS11Client.InitializeUserPIN(Const SecurityOfficerPIN, NewUserPIN: WideString): Boolean;
Function TPDFlibPKCS11Client.ChangeUserPIN(Const OldPIN, NewPIN: WideString): Boolean;

兩個操作都在設定的權杖上開啟自己的讀寫 session,不動簽署 session;InitializeUserPIN 以安全官身分登入後呼叫 C_InitPIN,ChangeUserPIN 以使用者身分登入後呼叫 C_SetPIN

PIN 緩衝區用後即清;缺少必要進入點的模組會回報錯誤,不會無聲失敗