TPDFlibPKCS11Client
Seguridad y firmas
Descripción
Carga en tiempo de ejecución un módulo PKCS #11 del proveedor y expone certificados y claves privadas que no están registrados con los proveedores CSP o KSP de WindowsEl cliente enumera los tokens presentes, abre una sesión persistente, autentica al usuario, empareja un certificado X.509 con una clave de firma por
CKA_ID binario y firma digests ya calculados mediante CKM_RSA_PKCS o CKM_ECDSAEl descubrimiento explícito sin certificado puede seleccionar una clave privada ML-DSA por etiqueta o ID binario, validar su
CKA_PARAMETER_SETCKM_ML_DSA
SignDigest y firmar mensajes originales mediante TPDFlibExternalDigestSignEventTPDFlib.OnExternalDigestSign implementa
Unidad
PDFlibPKCS11Construcción y ciclo de vida del 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 una DLL PKCS #11 Win32 o Win64 que exporta C_GetFunctionListLos clientes que usan la misma ruta comparten un módulo cargado y un ciclo de vida
C_Initialize/C_Finalize equilibradoEl cargador primero solicita
CKF_OS_LOCKING_OK
UseFunctionList; los módulos que no pueden proporcionar bloqueo interno quedan protegidos por un bloqueo de llamada compartido, mientras que los módulos conformes permiten que sesiones de clientes separadas se ejecuten concurrentementeUnloadModule admite proveedores enlazados estáticamente, incrustados o gestionados por la aplicación; el llamador debe mantener viva la tabla suministrada hasta
Detección y conexión de tokens
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 los slots presentes con reintentos acotados cuando un evento de hot-plug cambia el recuento, y TokenCount informa cuántos tokens encontró la última actualizaciónSeleccione un token con
SlotID, TokenLabel, TokenSerial o una combinación; una selección vacía tiene éxito solo cuando existe exactamente un token presente
TPDFlibPKCS11Token informa la descripción del slot, el fabricante, la etiqueta del token, el modelo, el número de serie, las banderas y los límites de longitud del PIN
Parámetros
| CertificateLabel | Filtro opcional CKA_LABEL UTF-8 para el objeto de certificado X.509 |
|---|---|
| CertificateID | Filtro opcional CKA_ID binario almacenado en un AnsiString |
| PrivateKeyLabel | Filtro opcional CKA_LABEL UTF-8 para la clave privada de firma |
| PrivateKeyID | CKA_ID binario opcional de la clave privada; cuando está vacío, se reutiliza el ID del certificado |
| CertificateOptional | Adopta False de forma predeterminada; cuando es True, se requiere una etiqueta o ID de clave privada y el descubrimiento acepta solo claves ML-DSA sin certificado X.509 |
CKA_SIGN=True
MLDSAParameterSet
CertificateDER, valida el DER del certificado y rechaza los tipos RSA/EC que no coinciden; el descubrimiento sin certificado exige una clave ML-DSA inequívoca y valida el conjunto de parámetros 44, 65 u 87El conjunto de parámetros ML-DSA resuelto se expone a través de ResolvedPrivateKeyIDEl certificado resuelto se expone a través de
Autenticación
| UserPIN | PIN de usuario de solo escritura codificado como UTF-8, comprobado contra los límites del token y borrado cuando se reemplaza o se destruye |
|---|---|
| UseProtectedAuthenticationPath | Pasa un PIN nulo cuando el token anuncia CKF_PROTECTED_AUTHENTICATION_PATH |
| ReadWriteSession | Agrega CKF_RW_SESSION; la firma normalmente necesita solo la sesión serial de solo lectura predeterminada |
Las claves con CKA_ALWAYS_AUTHENTICATE=True reciben un inicio de sesión específico del contexto después de cada C_SignInit exitoso
ClearPIN sobrescribe y libera el PIN configurado
Firma
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;Las firmas RSA usan CKM_RSA_PKCS bruto con un DigestInfo DER construido localmente, de modo que el token no hashea el digest PDF una segunda vezLas firmas ECDSA usan
CKM_ECDSA bruto; la salida P1363 del token se devuelve sin cambios para PDF_EXTERNAL_SIGNATURE_ECDSA_P1363 o se convierte a DER estricto para PDF_EXTERNAL_SIGNATURE_ECDSA_DER
SignMLDSA pasa el mensaje original a CKM_ML_DSA de una sola parte con parámetros de mecanismo vacíos, seleccionando el contexto vacío por defecto; es independiente de SignHash y de la callback de resumen CMS
Las longitudes de resumen SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256, SHA3-384 y SHA3-512 se validan antes de cualquier operación de clave privada
C_SignInit falla antes de que comience la firma, evitando operaciones duplicadas con la clave privada después de un fallo ambiguo de C_Sign
Ejemplo
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 y comportamiento en caso de fallo
Connected, KeyType, MLDSAParameterSet, AlwaysAuthenticate, FunctionListMajor y FunctionListMinor exponen el estado activo del proveedorLos métodos devuelven
False y establecen tanto LastReturnValue como LastError cuando fallan la carga del módulo, la selección del token, la autenticación, el descubrimiento de objetos, los límites de atributos, las comprobaciones de mecanismo o la firma
Véase también
OnExternalDigestSign, SetSignProcessExternalDigestSigner, SetSignProcessDigestAlgorithm, TPDFlibCSCClient
Administración de PIN
Function TPDFlibPKCS11Client.InitializeUserPIN(Const SecurityOfficerPIN, NewUserPIN: WideString): Boolean;
Function TPDFlibPKCS11Client.ChangeUserPIN(Const OldPIN, NewPIN: WideString): Boolean;Ambas operazioni abren su propia sesión de lectura/escritura en el token configurado y dejan intacta la sesión de firma; InitializeUserPIN inicia sesión como oficial de seguridad antes de llamar a C_InitPIN, y ChangeUserPIN inicia sesión como usuario antes de llamar a C_SetPIN
Los búferes de PIN se borran después del uso; un módulo sin el punto de entrada requerido informa un error en lugar de fallar en silencio