TPDFlibPKCS11Client
Segurança e assinaturas
Descrição
Carrega um módulo PKCS #11 de fornecedor em runtime e expõe certificados e chaves privadas não registrados nos provedores Windows CSP ou KSP
CKA_ID binário e assina digests já calculados por meio de CKM_RSA_PKCS ou CKM_ECDSAA descoberta explícita com certificado opcional pode selecionar uma chave privada ML-DSA por rótulo ou ID binário, validar seu
A descoberta com certificado opcional pode selecionar uma chave privada ML-DSA por rótulo ou ID binária, validar seu CKA_PARAMETER_SET e assinar mensagens originais por meio de CKM_ML_DSA
SignDigest e assinar mensagens originais por meio de TPDFlibExternalDigestSignEventTPDFlib.OnExternalDigestSign implementa
Unidade
PDFlibPKCS11Construção e ciclo de vida do módulo
Constructor TPDFlibPKCS11Client.Create;
Destructor TPDFlibPKCS11Client.Destroy;
Function TPDFlibPKCS11Client.LoadModule: Boolean;
Procedure TPDFlibPKCS11Client.UnloadModule;
Function TPDFlibPKCS11Client.UseFunctionList(FunctionList: PPLPKCS11FunctionList; AlreadyInitialized: Boolean): Boolean;ModulePath identifica uma DLL PKCS #11 Win32 ou Win64 que exporta C_GetFunctionList
C_Initialize/C_FinalizeO carregador primeiro solicita
O loader primeiro solicita CKF_OS_LOCKING_OK; módulos que não conseguem fornecer travamento interno são protegidos por um lock de chamada compartilhado, enquanto módulos em conformidade permitem sessões de cliente separadas executarem concorrentemente
UseFunctionList suporta provedores vinculados estaticamente, embutidos ou gerenciados pela aplicação; o chamador deve manter a tabela fornecida viva até UnloadModule ou destruição
Descoberta e conexão de token
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 enumera os slots presentes com nova tentativa limitada quando um evento hot-plug muda a contagem, e TokenCount informa quantos tokens a última atualização encontrouSelecione um token com
SlotID, TokenLabel, TokenSerial ou uma combinação; uma seleção vazia só tem sucesso quando existe exatamente um token presente
TPDFlibPKCS11Token informa a descrição do slot, o fabricante, o rótulo do token, o modelo, o número de série, os sinalizadores e os limites de comprimento do PIN
Parâmetros
| CertificateLabel | Filtro CKA_LABEL UTF-8 opcional para o objeto de certificado X.509 |
|---|---|
| CertificateID | Filtro CKA_ID binário opcional armazenado em um AnsiString |
| PrivateKeyLabel | Filtro CKA_LABEL UTF-8 opcional para a chave privada de assinatura |
| PrivateKeyID | CKA_ID binário opcional da chave privada; quando vazio, o ID do certificado é reutilizado |
| CertificateOptional | Assume False como padrão; quando True, um rótulo ou ID de chave privada é exigido e a descoberta aceita apenas chaves ML-DSA sem certificado X.509 |
A descoberta padrão exige um certificado e uma chave inequívocos, exige CKA_SIGN=True, valida o DER do certificado e rejeita divergências de tipo RSA/EC; a descoberta com certificado opcional exige uma chave ML-DSA inequívoca e valida o conjunto de parâmetros 44, 65 ou 87
MLDSAParameterSet
O certificado resolvido é exposto por CertificateDER e o ID da chave selecionada por ResolvedPrivateKeyID
Autenticação
| UserPIN | PIN de usuário somente escrita codificado em UTF-8, verificado contra os limites do token e apagado quando substituído ou destruído |
|---|---|
| UseProtectedAuthenticationPath | Passa um PIN nulo quando o token anuncia CKF_PROTECTED_AUTHENTICATION_PATH |
| ReadWriteSession | Adiciona CKF_RW_SESSION; a assinatura normalmente precisa apenas da sessão serial somente leitura padrão |
As chaves com CKA_ALWAYS_AUTHENTICATE=True recebem um login específico de contexto após cada C_SignInit bem-sucedido
ClearPIN sobrescreve e libera o PIN configurado
Assinatura
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;As assinaturas RSA usam CKM_RSA_PKCS bruto com um DigestInfo DER construído localmente, de modo que o token não calcula o hash do digest PDF uma segunda vezAs assinaturas ECDSA usam
CKM_ECDSA bruto; a saída P1363 do token é retornada inalterada para PDF_EXTERNAL_SIGNATURE_ECDSA_P1363 ou convertida para DER estrito para PDF_EXTERNAL_SIGNATURE_ECDSA_DER
SignMLDSA passa a mensagem original ao CKM_ML_DSA de parte única com parâmetros de mecanismo vazios, selecionando o contexto vazio padrão; ele é independente de SignHash e do callback de digest CMS
Os comprimentos de digest SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256, SHA3-384 e SHA3-512 são validados antes de qualquer operação de chave privada
C_SignInit falha antes de a assinatura começar, evitando operações duplicadas de chave privada após uma falha ambígua de C_Sign
Exemplo
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;Estado e comportamento em caso de falha
Connected, KeyType, MLDSAParameterSet, AlwaysAuthenticate, FunctionListMajor e FunctionListMinor expõem o estado ativo do provedorOs métodos retornam
False e definem tanto LastReturnValue quanto LastError quando o carregamento do módulo, a seleção de token, a autenticação, a descoberta de objetos, os limites de atributos, as verificações de mecanismo ou a assinatura falham
Veja também
OnExternalDigestSign, SetSignProcessExternalDigestSigner, SetSignProcessDigestAlgorithm, TPDFlibCSCClient
Administração de PIN
Function TPDFlibPKCS11Client.InitializeUserPIN(Const SecurityOfficerPIN, NewUserPIN: WideString): Boolean;
Function TPDFlibPKCS11Client.ChangeUserPIN(Const OldPIN, NewPIN: WideString): Boolean;Ambas as operações abrem sua própria sessão de leitura/gravação no token configurado e deixam a sessão de assinatura intacta; InitializeUserPIN entra como o security officer antes de chamar C_InitPIN, e ChangeUserPIN entra como o usuário antes de chamar C_SetPIN
Buffers de PIN são apagados após o uso; um módulo sem o ponto de entrada exigido relata um erro em vez de falhar silenciosamente