TPDFlibPKCS11Client
Безопасность и подписи
Описание
Загружает модуль PKCS #11 поставщика во время выполнения и раскрывает сертификаты и закрытые ключи, не зарегистрированные в провайдерах Windows CSP или KSP
CKA_ID и подписывает уже вычисленные дайджесты через CKM_RSA_PKCS или CKM_ECDSAЯвное обнаружение с необязательным сертификатом может выбрать закрытый ключ ML-DSA по метке или бинарному ID, проверить его
Обнаружение с необязательным сертификатом может выбрать закрытый ключ ML-DSA по метке или бинарному идентификатору, проверить его CKA_PARAMETER_SET и подписывать исходные сообщения через CKM_ML_DSA
SignDigest и подписывать исходные сообщения через TPDFlibExternalDigestSignEventTPDFlib.OnExternalDigestSign реализует
Единица
PDFlibPKCS11Создание и жизненный цикл модуля
Constructor TPDFlibPKCS11Client.Create;
Destructor TPDFlibPKCS11Client.Destroy;
Function TPDFlibPKCS11Client.LoadModule: Boolean;
Procedure TPDFlibPKCS11Client.UnloadModule;
Function TPDFlibPKCS11Client.UseFunctionList(FunctionList: PPLPKCS11FunctionList; AlreadyInitialized: Boolean): Boolean;ModulePath идентифицирует DLL PKCS #11 для Win32 или Win64, экспортирующую C_GetFunctionList
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
Параметры
| CertificateLabel | Необязательный фильтр UTF-8 CKA_LABEL для объекта сертификата X.509 |
|---|---|
| CertificateID | Необязательный бинарный фильтр CKA_ID, хранящийся в AnsiString |
| PrivateKeyLabel | Необязательный фильтр UTF-8 CKA_LABEL для закрытого подписывающего ключа |
| PrivateKeyID | Необязательный бинарный CKA_ID закрытого ключа; когда пуст, повторно используется ID сертификата |
| CertificateOptional | По умолчанию False; когда True, требуется метка или ID закрытого ключа, а обнаружение принимает только ключи ML-DSA без сертификата X.509 |
Обнаружение по умолчанию требует однозначных сертификата и ключа, требует CKA_SIGN=True, проверяет DER сертификата и отклоняет несовпадения типов RSA/EC; обнаружение с необязательным сертификатом требует однозначного ключа ML-DSA и проверяет набор параметров 44, 65 или 87
MLDSAParameterSet
Разрешенный сертификат раскрывается через CertificateDER, а идентификатор выбранного ключа — через ResolvedPrivateKeyID
Аутентификация
| UserPIN | PIN пользователя только для записи, закодированный в UTF-8, проверяемый по границам токена и стираемый при замене или уничтожении |
|---|---|
| UseProtectedAuthenticationPath | Передаёт нулевой PIN, когда токен объявляет CKF_PROTECTED_AUTHENTICATION_PATH |
| 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 или конвертируется в строгий DER для PDF_EXTERNAL_SIGNATURE_ECDSA_DER
SignMLDSA передает исходное сообщение в однопартовый CKM_ML_DSA с пустыми параметрами механизма, выбирая пустой контекст по умолчанию; он независим от SignHash и callback дайджеста 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 стираются после использования; модуль без требуемой точки входа сообщает об ошибке вместо беззвучного сбоя
Буферы PIN стираются после использования; модуль без требуемой точки входа сообщает об ошибке вместо тихого отказа