TPDFlibPKCS11Client
セキュリティと署名
説明
ベンダーのPKCS #11モジュールを実行時に読み込み、Windows CSPやKSPプロバイダーに登録されていない証明書と秘密鍵を公開します
クライアントは存在するトークンを列挙し、永続セッションを開き、ユーザーを認証し、バイナリのCKA_IDでX.509証明書と署名鍵をペアにし、計算済みのダイジェストをCKM_RSA_PKCSまたはCKM_ECDSAで署名します
明示的な証明書省略可能の探索は、ラベルまたはバイナリIDでML-DSA秘密鍵を選択し、そのCKA_PARAMETER_SETを検証し、元のメッセージをCKM_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の生存期間を1つ共有します
ローダーは最初に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、またはその組み合わせでトークンを選択します。空の選択は、存在するトークンがちょうど 1 つの場合にのみ成功します
TPDFlibPKCS11Token はスロットの説明、製造元、トークンラベル、モデル、シリアル番号、フラグ、PIN 長の範囲を報告します
アイデンティティの選択
| CertificateLabel | X.509証明書オブジェクトのオプションのUTF-8 CKA_LABELフィルターです |
|---|---|
| CertificateID | AnsiStringに保存されるオプションのバイナリCKA_IDフィルターです |
| PrivateKeyLabel | 秘密署名鍵のオプションのUTF-8 CKA_LABELフィルターです |
| PrivateKeyID | オプションのバイナリ秘密鍵CKA_IDです。空の場合は証明書のIDが再利用されます |
| CertificateOptional | 既定はFalseです。Trueの場合は秘密鍵のラベルまたはIDが必要となり、探索はX.509証明書を持たないML-DSA鍵だけを受け入れます |
既定の探索は曖昧さのない証明書と鍵の1組を要求し、CKA_SIGN=Trueを要求し、証明書DERを検証し、RSA/ECの型不一致を拒否します。証明書省略可能の探索は曖昧さのないML-DSA鍵を要求し、パラメーターセット44、65、87を検証します
解決されたML-DSAパラメーターセットはMLDSAParameterSetで公開されます
解決された証明書はCertificateDERで、選択された鍵IDはResolvedPrivateKeyIDで公開されます
認証
| UserPIN | UTF-8 でエンコードされた書き込み専用のユーザー PIN。トークンの範囲に対して検査され、置き換えや破棄の際に消去されます |
|---|---|
| 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署名はローカルで構築されたDER DigestInfoを使う生のCKM_RSA_PKCSを使用するため、トークンがPDFダイジェストを2度ハッシュすることはありません
ECDSA署名は生のCKM_ECDSAを使います。トークンのP1363出力はPDF_EXTERNAL_SIGNATURE_ECDSA_P1363ではそのまま返され、PDF_EXTERNAL_SIGNATURE_ECDSA_DERでは厳密なDERへ変換されます
SignMLDSAは元のメッセージを、空のメカニズムパラメーターを持つシングルパートのCKM_ML_DSAへ渡し、既定の空コンテキストを選択します。SignHashやCMSダイジェストコールバックとは独立です
SHA-1、SHA-256、SHA-384、SHA-512、SHA3-256、SHA3-384、SHA3-512のダイジェスト長は、秘密鍵操作の前に検証されます
失われたセッションの再オープンと再試行は、署名開始前にC_SignInitが失敗した場合にだけ行われ、曖昧な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;両操作は設定されたトークン上に独自の読み書きセッションを開き、署名セッションには触れません。InitializeUserPINはC_InitPINの呼び出し前にセキュリティオフィサーとしてログインし、ChangeUserPINはC_SetPINの呼び出し前にユーザーとしてログインします
PINバッファは使用後に消去されます。必要なエントリポイントを持たないモジュールは、黙って失敗する代わりにエラーを報告します