РабоÑнаÑа ÑÑеда, коÑÑо ÑвÑÑзва валидиÑанеÑо на ÑÑвмеÑÑимоÑÑ Ñ ÑиÑÑовоÑо подпиÑване, ÑÑÑбва да кооÑдиниÑа ÑеÑиÑи ÑÑÑпки в опÑеделен Ñед и да ги поддÑÑжа обвÑÑзани Ñ ÐµÐ´Ð¸Ð½ и ÑÑÑ Ð½Ð°Ð±Ð¾Ñ Ð¾Ñ Ð±Ð°Ð¹Ñове пÑез ÑÐµÐ»Ð¸Ñ Ð¿ÑоÑеÑ. Ð¢Ñ Ð¸Ð·Ð¿ÑлнÑва пÑедваÑиÑелна пÑовеÑка за PDF/A или PDF/UA. ÐÑилага Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¸Ñе коÑекÑии ÑпоÑед конÑÑаÑаÑииÑе и запиÑва коÑигиÑана веÑÑиÑ. ÐодпиÑва ÑоÑно Ñази веÑÑиÑ. ÐакÑÐ°Ñ Ð¿ÑоÑиÑа обÑаÑно подпиÑÐ°Ð½Ð¸Ñ Ñайл и поÑвÑÑждава, Ñе подпиÑÑÑ Ð½Ð°Ð¸ÑÑина го покÑива. Този Ñед не е козмеÑиÑен. ÐÑопÑÑнеÑе обÑаÑноÑо ÑеÑене и Ñе довеÑÑваÑе на ÑобÑÑÐ²ÐµÐ½Ð¸Ñ Ñи пÑÑ Ð·Ð° запиÑ; оÑÑавеÑе пÑовеÑкаÑа да Ñе изпÑлни ÑÑеÑÑ Ð³ÑеÑна веÑÑÐ¸Ñ Ð¸ ваÑиÑÑ Ð¾ÑÑÐµÑ Ð·Ð° ÑÑвмеÑÑимоÑÑ Ñе опиÑва Ñайл, койÑо никога не ÑÑе изпÑаÑали.
ЧаÑÑÑа, коÑÑо повеÑеÑо ÑобÑÑвени пÑоÑеÑи обÑÑкваÑ, е вÑÑзкаÑа Ð¼ÐµÐ¶Ð´Ñ Ð²Ð°Ð»Ð¸Ð´Ð¸ÑанеÑо и подпиÑванеÑо. СÑаÑÑиÑайÑе ги каÑо два оÑделни инÑÑÑÑменÑа Ñ Ð¼ÐµÐ¶Ð´Ð¸Ð½ÐµÐ½ пÑÐ¾Ñ Ð¾Ð´ за коÑигиÑане и Ñе Ñе поÑвÑÑ Ð¿Ð¾Ð½Ðµ ÑÑи оÑделни веÑÑии на Ñайла, вÑÑка ÑÑÑ ÑобÑÑвени байÑове. ÐÑÑеÑÑÑ Ð·Ð° пÑовеÑка, койÑо пÑедоÑÑавÑÑе на одиÑоÑ, опиÑва една Ð¾Ñ ÑÑÑ . ÐодпиÑÑÑ Ð·Ð°Ð¼ÑазÑва дÑÑга. ÐиÑо вÑв Ñайла не казва, Ñе Ñе Ñа една и ÑÑÑа веÑÑиÑ, и ÑеÑÑо Ñова не е Ñака. PDFlibPas, библиоÑекаÑа за ÑазÑабоÑка на PDF Ð¾Ñ losLab за Delphi и C++Builder, поÑÑÐ°Ð²Ñ Ð¿ÑедваÑиÑелнаÑа пÑовеÑка и PAdES подпиÑванеÑо зад един Ð¾Ð±Ñ ÐºÐ»Ð°Ñ ÑаÑада, Ñака Ñе ÑÑлаÑа поÑледоваÑелноÑÑ Ð¼Ð¾Ð¶Ðµ да Ñе изпÑлнÑва в един пÑоÑеÑ, койÑо никога не гÑби Ñледа за кои байÑове ÑÑава дÑма. ÐÑÑко извикване по-Ð´Ð¾Ð»Ñ ÑÑÑеÑÑвÑва в библиоÑекаÑа днеÑ, какÑо и вÑеки опиÑан капан.
ТÑи веÑÑии на един докÑÐ¼ÐµÐ½Ñ Ð¸ как Ñе оÑваÑÑ ÑазликаÑа
ÐÑебÑойÑе запиÑваниÑÑа. ÐÑигиналÑÑ Ð¿ÑиÑÑига Ð¾Ñ Ð²Ñ Ð¾Ð´ÑÑÐ¸Ñ Ð¿Ð¾Ñок. ÐÑÐ¾Ñ Ð¾Ð´ÑÑ Ð·Ð° коÑекÑÐ¸Ñ Ð³Ð¾ заÑежда, вклÑÑва Ñежим за ÑÑвмеÑÑимоÑÑ Ð¸ запиÑва коÑигиÑана веÑÑиÑ. ÐÑÐ¾Ñ Ð¾Ð´ÑÑ Ð·Ð° подпиÑване Ð´Ð¾Ð±Ð°Ð²Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñ ÐºÐ°Ñо инкÑеменÑална акÑÑализаÑиÑ, коеÑо е ÑÑеÑи запиÑ. ТÑи запиÑваниÑ, ÑÑи оÑоÑÐ¼Ð»ÐµÐ½Ð¸Ñ Ð½Ð° байÑовеÑе и един оÑÑÐµÑ Ð·Ð° пÑовеÑка не ознаÑÐ°Ð²Ð°Ñ Ð½Ð¸Ñо, оÑвен ако не Ñе поÑоÑи ÐºÐ¾Ñ Ð¾Ñ ÑÑиÑе веÑÑии покÑиваÑ. SHA-256 Ñ ÐµÑ Ð½Ð° Ñайла, запиÑан до вÑÑка пÑовеÑка и вÑеки подпиÑ, е леÑен наÑин да докажеÑе, Ñе валидиÑанаÑа веÑÑÐ¸Ñ Ðµ ÑоÑно Ñази, коÑÑо ÑÑе подпиÑали.
Ðдно Ð¾Ñ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸ÑÑа на библиоÑекаÑа заÑилва Ñази диÑÑиплина оÑе повеÑе. ÐоÑекÑииÑе за ÑÑвмеÑÑимоÑÑ, поиÑкани ÑÑез SetPDFAMode или SetPDFUAMode, не Ð²Ð»Ð¸Ð·Ð°Ñ Ð² Ñила в моменÑа на извикванеÑо им. Те Ñе пÑÐ¸Ð»Ð°Ð³Ð°Ñ Ð¿Ð¾ вÑеме на запиÑванеÑо. ÐвÑомаÑиÑниÑе коÑекÑии, каÑо пÑинÑдиÑелно задаване на Ñлагове за пеÑÐ°Ñ Ð½Ð° аноÑаÑии или пÑиÑвоÑване на Ñед за ÑабÑлаÑÐ¸Ñ Ð² PDF/UA, Ñе запиÑÐ²Ð°Ñ Ð² изÑ
Ð¾Ð´Ð½Ð¸Ñ Ñайл и никÑде дÑÑгаде, Ñака Ñе пÑовеÑка на докÑменÑа, койÑо ÑокÑ-Ñо ÑÑе "коÑигиÑали" в памеÑÑа, не ви казва ниÑо за байÑовеÑе, изпÑаÑени кÑм модÑла за подпиÑване. ÐапиÑеÑе пÑÑво, Ñлед коеÑо напÑавеÑе пÑовеÑка на запиÑÐ°Ð½Ð¸Ñ Ñайл. СÑÑÑоÑниеÑо в памеÑÑа е Ñамо ÑеÑнова; Ñамо ÑайлÑÑ Ð½Ð° диÑка е Ñеален.
ÐÑовеÑка Ð¾Ñ Ð´Ð¸Ñк и нÑлаÑа, коÑÑо ознаÑава две неÑа
ÐÑновнаÑа ÑоÑка за пÑовеÑка на ÑÑвмеÑÑимоÑÑ Ðµ CheckFileCompliance(FileName, Password, ComplianceTest, Options). ТеÑÑ 1 избиÑа PDF/A (ISO 19005), ÑеÑÑ 2 избиÑа PDF/UA (ISO 14289). ФÑнкÑиÑÑа оÑваÑÑ Ñайла ÑÑез ÑÑÑийминг ÑеÑеÑа на библиоÑекаÑа, Ñака Ñе нÑма нÑжда пÑÑво да използваÑе LoadFromFile, и вÑÑÑа деÑкÑипÑÐ¾Ñ Ð½Ð° ÑпиÑÑк Ñ Ð½Ð¸Ð·Ð¾Ð²Ðµ, ÑÑдÑÑÐ¶Ð°Ñ Ð¿Ð¾ една конÑÑаÑаÑÐ¸Ñ Ð·Ð° вÑеки запиÑ:
var
PDF: TPDFlib;
ListID, I: Integer;
begin
PDF := TPDFlib.Create;
try
ListID := PDF.CheckFileCompliance('invoice-fixed.pdf', '', 1, 0); // 1 = PDF/A
if ListID = 0 then
begin
if PDF.LastErrorCode <> 0 then
raise Exception.Create('Preflight could not read the file')
else
Writeln('No PDF/A findings');
end
else
begin
for I := 0 to PDF.GetStringListCount(ListID) - 1 do
Writeln(PDF.GetStringListItem(ListID, I));
PDF.ReleaseStringList(ListID);
end;
finally
PDF.Free;
end;
end;
ÐапанÑÑ Ðµ вÑв вÑÑнаÑаÑа ÑÑойноÑÑ Ð¸ е Ð¾Ñ Ñип, койÑо пÑеминава ÑÑпеÑно пÑез вÑеки ÑÑандаÑÑен ÑеÑÑ. ÐÑлаÑа ознаÑава "нÑма конÑÑаÑаÑии". ÐÑлаÑа ÑÑÑо Ñака ознаÑава "ÑайлÑÑ Ð½Ðµ може да бÑде оÑвоÑен", ÑÑй каÑо имплеменÑаÑиÑÑа вÑÑÑа 0 винаги, когаÑо ÑпиÑÑкÑÑ Ñ ÑезÑлÑаÑи е пÑазен, вклÑÑиÑелно пÑи гÑеÑка в ÑеÑенеÑо. РабоÑна ÑÑеда, коÑÑо ÑÑлкÑва 0 каÑо зелена ÑвеÑлина, безпÑоблемно Ñе одобÑи Ñайл, заклÑÑен Ð¾Ñ Ð´ÑÑг пÑоÑеÑ. ÐомбиниÑанеÑо на извикванеÑо Ñ LastErrorCode, какÑо е показано по-гоÑе, ÑазгÑаниÑава дваÑа ÑлÑÑаÑ. ÐÑовеÑÑваÑиÑÑ Ð¼Ð¾Ð´Ñл ÑÑÑо Ñака оÑваÑÑ Ñайла в Ñежим на ÑподелÑне без пÑаво на запиÑ, Ñака Ñе ако ваÑаÑа ÑÑÑпка по коÑигиÑане вÑе оÑе дÑÑжи оÑвоÑен поÑок за запиÑ, пÑовеÑкаÑа Ñе Ñе пÑовали по пÑиÑина, ÑвÑÑзана Ñ Ð½ÐµÐ·Ð°ÑвоÑен поÑок, а не ÑÑÑ ÑÑвмеÑÑимоÑÑÑа.
ÐогаÑо Ñовек, а не авÑомаÑизиÑан пÑоÑеÑ, ÑÑÑбва да пÑоÑеÑе конÑÑаÑаÑииÑе, CreatePreflightReport ги пÑедÑÑÐ°Ð²Ñ ÐºÐ°Ñо ÑеÑим оÑÑеÑ. ComparePreflightReports ÑÑавнÑва две пÑовеÑки, коеÑо е Ñдобен наÑин да Ñе покаже, Ñе коÑекÑииÑе Ñа изÑиÑÑили пÑÑвонаÑалниÑе пÑоблеми, без да вÑÐ²ÐµÐ¶Ð´Ð°Ñ Ð½Ð¾Ð²Ð¸.
ÐодпиÑване на пÑовеÑенаÑа веÑÑÐ¸Ñ ÑÑÑ SignProcess
След каÑо запиÑанаÑа веÑÑÐ¸Ñ Ð¿Ñемине пÑовеÑкаÑа и нейниÑÑ Ñ ÐµÑ Ðµ ÑегиÑÑÑиÑан, подпиÑеÑе ÑоÑно Ñози Ñайл и никой дÑÑг. API за SignProcess пÑилиÑа на ÑÑÑоиÑел (builder). ÐÑвоÑеÑе деÑкÑипÑÐ¾Ñ Ð½Ð° пÑоÑеÑ, конÑигÑÑиÑайÑе го Ñед по Ñед, поÑвÑÑдеÑе пÑомениÑе и пÑоÑеÑеÑе кода на ÑезÑлÑаÑа.
ProcessID := PDF.NewSignProcessFromFile('invoice-fixed.pdf', '');
if ProcessID = 0 then
raise Exception.Create('Cannot open source for signing');
PDF.SetSignProcessField(ProcessID, 'ApprovalSig');
PDF.SetSignProcessPFXFromFile(ProcessID, 'company.pfx', PfxPassword);
PDF.SetSignProcessInfo(ProcessID, 'Invoice approval', 'Berlin', 'billing@example.com');
PDF.SetSignProcessCustomSubFilter(ProcessID, 'ETSI.CAdES.detached'); // PAdES baseline
PDF.SetSignProcessDigestAlgorithm(ProcessID, 2); // SHA-256
PDF.SetSignProcessReserveContentsBytes(ProcessID, 8192); // room for a later timestamp
PDF.EndSignProcessToFile(ProcessID, 'invoice-signed.pdf');
if PDF.GetSignProcessResult(ProcessID) <> 1 then
Writeln('Sign failed, code ', PDF.GetSignProcessResult(ProcessID));
PDF.ReleaseSignProcess(ProcessID);
Ðва Ñеда в Ñази поÑледоваÑелноÑÑ Ð¸Ð¼Ð°Ñ Ð¿Ð¾-голÑмо знаÑение, оÑколкоÑо изглежда. SetSignProcessCustomSubFilter Ñ ETSI.CAdES.detached избиÑа PAdES подпиÑ, ÑÑглаÑно ETSI EN 319 142-1, вмеÑÑо оÑÑаÑÑлаÑа ÑÐ°Ð¼Ð¸Ð»Ð¸Ñ adbe.pkcs7.detached, коеÑо опÑÐµÐ´ÐµÐ»Ñ Ð´Ð°Ð»Ð¸ евÑопейÑки валидаÑÐ¾Ñ Ñе пÑиеме подпиÑа или Ñе го маÑкиÑа каÑо невалиден. SetSignProcessReserveContentsBytes запÑлва конÑейнеÑа /Contents Ñ Ð¿Ñазно пÑоÑÑÑанÑÑво, каÑо избÑаниÑÑ ÑÑк ÑÐ°Ð·Ð¼ÐµÑ Ðµ ÑеÑение за бÑдеÑеÑо: ако Ñе наложи добавÑне на вÑемеви пеÑаÑ, ÑазÑиÑениÑÑ CMS ÑÑÑбва да Ñе побеÑе в запазеноÑо Ñега пÑоÑÑÑанÑÑво, ÑÑй каÑо Ñо не може да Ñе ÑвелиÑи по-кÑÑно без повÑоÑно подпиÑване на ÑÐµÐ»Ð¸Ñ Ð´Ð¾ÐºÑменÑ. ÐапазеÑе ÑвÑÑде много и гÑбиÑе нÑколко килобайÑа, но ако запазеноÑо мÑÑÑо е ÑвÑÑде малко, ÑÑÑпкаÑа за вÑемеви пеÑÐ°Ñ Ñе Ñе пÑовали Ñлед меÑеÑи Ñ Ð³ÑеÑка за пÑепÑлване, коÑÑо ÑÑÑдно Ñе ÑвÑÑжеÑе Ñ Ñози конкÑеÑен Ñед.
GetSignProcessResult вÑÑÑа код на ÑезÑлÑаÑ, а не бÑлева ÑÑойноÑÑ, и Ñези кодове Ñи ÑÑÑÑва да Ñе запиÑваÑ. 1 ознаÑава ÑÑпеÑ
, 4 - гÑеÑна PDF паÑола, 7 - гÑеÑна паÑола за ÑеÑÑиÑикаÑ, 9 - PFX Ñайл без ÑаÑÑен клÑÑ, 11 - гÑеÑка пÑи пÑилаганеÑо на подпиÑа. Ðко ги обединиÑе в обикновено вÑÑно/гÑеÑно, Ñе загÑбиÑе единÑÑвенаÑа инÑоÑмаÑиÑ, коÑÑо ÑазгÑаниÑава пÑоблема Ñ Ð³ÑеÑна паÑола Ð¾Ñ Ñози Ñ ÐºÐ»ÑÑ Ð±ÐµÐ· ÑаÑÑна ÑаÑÑ. ÐапиÑвайÑе ÑелоÑиÑленаÑа ÑÑойноÑÑ.
ÐбÑаÑно ÑеÑене: Ð¾Ð´Ð¸Ñ Ð½Ð° ÑокÑ-Ñо ÑÑÐ·Ð´Ð°Ð´ÐµÐ½Ð¸Ñ Ñайл
ÐÐ¸ÐºÐ¾Ñ ÑабоÑна ÑÑеда не ÑÑÑбва да Ñе довеÑÑва ÑлÑпо на пÑÑÑ, по койÑо е запиÑан ÑайлÑÑ, койÑо пÑедÑÑои да ÑеÑÑиÑиÑиÑа. ÐдиÑниÑÑ ÐºÐ»Ð°Ñ TPDFlibSignDoc оÑваÑÑ Ð¾Ñново подпиÑÐ°Ð½Ð¸Ñ ÑезÑлÑÐ°Ñ Ð¸ ÑеÑе запиÑиÑе в ÑеÑника на подпиÑа диÑекÑно Ð¾Ñ Ð´Ð¸Ñка:
var
Doc: TPDFlibSignDoc;
Names: TStringList;
FS: TFileStream;
I: Integer;
SourceSize, RangeStart, GapStart, TailStart, TailLen: Int64;
begin
// Capture the size before Open: the audit object holds a share lock on the file
FS := TFileStream.Create('invoice-signed.pdf', fmOpenRead or fmShareDenyNone);
SourceSize := FS.Size;
FS.Free;
Doc := TPDFlibSignDoc.Create;
Names := TStringList.Create;
try
if not Doc.Open('invoice-signed.pdf', '', False) then Exit;
Doc.GetSignatureFieldNames(Names);
for I := 0 to Names.Count - 1 do
if Doc.GetSignatureValueObjNum(Names[I]) > 0 then // > 0 means the field is signed
begin
RangeStart := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 11)));
GapStart := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 12)));
TailStart := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 13)));
TailLen := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 14)));
if (RangeStart = 0) and (TailStart + TailLen = SourceSize) then
Writeln(Names[I], ': signature covers the file to EOF')
else
Writeln(Names[I], ': earlier revision, or unusual ByteRange layout');
end;
Doc.Close;
finally
Names.Free;
Doc.Free;
end;
end;
ÐÑгÑменÑиÑе на ValueKey ÑÑоÑвеÑÑÑÐ²Ð°Ñ Ð½Ð° запиÑи в ÑеÑника. ÐлÑÑ 0 вÑÑÑа ÑÑÑÐ¾Ð²Ð¸Ñ CMS Ð¾Ñ /Contents, клÑÑове 2 и 3 - именаÑа на /Filter и /SubFilter, а Ð¾Ñ 11 до 14 - ÑеÑиÑиÑе ÑиÑла на ByteRange. ТекÑÑовиÑе ÑÑойноÑÑи Ñе извлиÑÐ°Ñ ÑÑез GetSignatureTextValueByName: клÑÑ 0 е деклаÑиÑаноÑо вÑеме на подпиÑване, а клÑÑ 5 ÑазгÑаниÑава обикновен Sig Ð¾Ñ DocTimeStamp, коеÑо е важно, когаÑо докÑменÑÑÑ ÑÑдÑÑжа и двеÑе.
ÐземанеÑо на ÑазмеÑа на Ñайла в гоÑнаÑа ÑаÑÑ Ð½Ð° Ñози пÑÐ¸Ð¼ÐµÑ Ðµ ÑÑÑÑкÑÑÑно важно, а не пÑоÑÑо поÑиÑÑване на кода. TPDFlibSignDoc.Open дÑÑжи Ñайла под огÑаниÑаваÑо заклÑÑване за ÑподелÑне пÑез ÑÐµÐ»Ð¸Ñ Ñи жизнен ÑикÑл, Ñака Ñе вÑеки пÑоÑеÑ, койÑо изиÑква ÑÑÑовиÑе байÑове (Ñ
еÑиÑане на подпиÑÐ°Ð½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½, пÑеизÑиÑлÑване на CMS дайджеÑÑа), ÑÑÑбва да пÑоÑеÑе Ñайла, пÑеди да извика Open. ÐемонÑÑÑаÑионниÑÑ Ð¿ÑÐ¾ÐµÐºÑ SigningWorkbench на ÑамаÑа библиоÑека пÑÑво ÑеÑе ÑÐµÐ»Ð¸Ñ Ñайл в памеÑÑа ÑоÑно поÑади Ñази пÑиÑина. РабоÑна ÑÑеда, коÑÑо игноÑиÑа Ñози Ñед на опеÑаÑии, Ñе Ñе пÑÐ¾Ð²Ð°Ð»Ñ Ð¿Ñоизволно на маÑинаÑа, коÑÑо загÑби конкÑÑенÑиÑÑа за доÑÑÑп.
ÐÑиÑмеÑика на ByteRange, коÑÑо доказва покÑиÑиеÑо
ÐÑавилниÑÑ Ñайл Ñ ÐµÐ´Ð¸Ð½Ð¸Ñен Ð¿Ð¾Ð´Ð¿Ð¸Ñ Ð¸Ð¼Ð° ByteRange вÑв ÑоÑÐ¼Ð°Ñ [0 a b c]: покÑиÑиеÑо запоÑва Ð¾Ñ Ð¾ÑмеÑÑване 0, пÑопÑÑка ÑеÑÑнадеÑеÑиÑÐ½Ð¸Ñ ÐºÐ¾Ð½ÑÐµÐ¹Ð½ÐµÑ /Contents Ð¼ÐµÐ¶Ð´Ñ 'a' и 'b', и пÑодÑлжава до Ð±Ð°Ð¹Ñ b+c. ÐогаÑо ÑÑмаÑа b+c е Ñавна на ÑазмеÑа на Ñайла, подпиÑÑÑ Ð¿Ð¾ÐºÑива вÑиÑко до кÑÐ°Ñ Ð½Ð° Ñайла, коеÑо е желаниÑÑ ÑезÑлÑаÑ. ÐогаÑо ÑÑойноÑÑÑа е по-малка, нÑкой е добавил инкÑеменÑална акÑÑализаÑÐ¸Ñ Ñлед полаганеÑо на подпиÑа. Това е напÑлно допÑÑÑимо ÑÑглаÑно ISO 32000-1 §12.8, ÑÑй каÑо попÑлванеÑо на ÑоÑмÑлÑÑи, вÑоÑи Ð¿Ð¾Ð´Ð¿Ð¸Ñ Ð¸ DSS ÑеÑник Ñе добавÑÑ ÑоÑно по Ñози наÑин. Това е и ÑакÑÑÑ, койÑо одиÑнаÑа Ñледа ÑÑÑбва да запиÑе в моменÑа на подпиÑване, вмеÑÑо да го вÑзÑÑановÑва пÑи евенÑÑален ÑпоÑ.
СледеÑе ÑиÑинаÑа на ÑелоÑиÑлениÑе Ñипове, докаÑо пÑавиÑе Ñези изÑиÑлениÑ. ФÑнкÑиÑÑа GetSignProcessByteRange Ð¾Ñ Ð¾ÑÐ½Ð¾Ð²Ð½Ð¸Ñ API вÑÑÑа 32-биÑово ÑÑло ÑиÑло, но базовиÑе ÑÑойноÑÑи Ñа Ð¾Ñ Ñип Int64, Ñака Ñе пÑи Ñайл над 2 GB доÑÑÑпÑÑ Ð¿Ñез оÑÐ½Ð¾Ð²Ð½Ð¸Ñ API безÑÑмно Ñе ÑÑкÑаÑи ÑÑойноÑÑÑа. ÐзползвайÑе клаÑÐ¾Ð²Ð¸Ñ Ñлой TPDFlibSigner.GetByteRange, койÑо вÑÑÑа Int64, или анализиÑайÑе ÑÑойноÑÑиÑе Ð¾Ñ GetSignatureValueByName, какÑо е показано в одиÑÐ½Ð¸Ñ ÐºÐ¾Ð´ по-гоÑе.
Ðакво оÑÑÐ°Ð²Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾ÑекаÑа на ваÑ
Ðве гÑаниÑи е по-добÑе да бÑÐ´Ð°Ñ Ð¿ÑоÑÑени по вÑеме на пÑоекÑиÑанеÑо, а не в поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ. ÐÑновниÑÑ API на TPDFlib не ÑÑдÑÑжа обвивка за пÑовеÑка на подпиÑи. ÐÑипÑогÑаÑÑкаÑа пÑовеÑка Ñе намиÑа едно ниво по-надолÑ, в TPDFlibSignatureVerifier, ÑийÑо меÑод VerifySignature вÑÑÑа ÑезÑлÑÐ°Ñ Ð·Ð° валиден, невалиден или неизвеÑÑен подпиÑ. СÑÑо Ñака нÑма вгÑаден HTTP ÐºÐ»Ð¸ÐµÐ½Ñ Ð·Ð° ÑÑÑвÑÑи за вÑемеви пеÑÐ°Ñ Ð¿Ð¾ RFC 3161. ÐиблиоÑекаÑа изÑиÑлÑва Ñ
еÑа за изпÑаÑане и вгÑажда обÑаÑно допÑÐ»Ð½ÐµÐ½Ð¸Ñ CMS, Ñлед каÑо полÑÑи Ñокен, но мÑежоваÑа комÑникаÑÐ¸Ñ Ñ TSA е ваÑа задаÑа. РдвеÑе ÑÑнкÑионалноÑÑи Ñе Ð¾Ð±Ð²Ð¸Ð²Ð°Ñ Ð»ÐµÑно, но е изклÑÑиÑелно непÑиÑÑно да ÑÑÑановиÑе липÑаÑа им ÑедмиÑа пÑеди Ñелийз, Ñака Ñе ги пÑедвидеÑе оÑе в ÑамоÑо наÑало.
ÐÑпÑоÑÑÑ Ð·Ð° ÑÑвмеÑÑимоÑÑÑа ÑÑÑбва да бÑде изÑÑнен пÑедваÑиÑелно, ÑÑй каÑо Ñой опÑÐµÐ´ÐµÐ»Ñ ÐºÑде Ñе поÑÑÐ°Ð²Ñ Ð¿Ð¾ÑледнаÑа заÑиÑа: наÑÑÑава ли добавÑнеÑо на Ð¿Ð¾Ð´Ð¿Ð¸Ñ ÑÑвмеÑÑимоÑÑÑа Ñ PDF/A? Ðе и Ñамо по Ñебе Ñи. ÐодпиÑÑÑ Ñе Ð´Ð¾Ð±Ð°Ð²Ñ ÐºÐ°Ñо инкÑеменÑална акÑÑализаÑиÑ, а ÑÑандаÑÑиÑе Ð¾Ñ ISO 19005-2 наÑаÑÑк изÑиÑно позволÑÐ²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñани докÑменÑи. УловкаÑа е вÑв визÑÐ°Ð»Ð½Ð¸Ñ Ð¸Ð·Ð³Ð»ÐµÐ´ на подпиÑа, койÑо Ñледва ÑÑÑиÑе пÑавила каÑо вÑÑко дÑÑго ÑÑдÑÑжание на ÑÑÑаниÑаÑа, вклÑÑиÑелно изиÑкваниÑÑа за вгÑадени ÑÑиÑÑове и липÑа на ÑвеÑове, завиÑеÑи Ð¾Ñ ÑÑÑÑойÑÑвоÑо. Така Ñе поÑледноÑо ниво на пÑовеÑка в ÑабоÑнаÑа ÑÑеда е оÑе едно ÑÑаÑÑиÑане на валидаÑиÑ, Ñози пÑÑ Ð²ÑÑÑ
Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ ÑезÑлÑаÑ. ÐзползвайÑе CheckFileCompliance каÑо бÑÑза авÑомаÑизиÑана пÑовеÑка в пÑоÑеÑа, но вÑе пак пÑовеÑÑвайÑе ÑиналниÑе веÑÑии Ñ Ð½ÐµÐ·Ð°Ð²Ð¸Ñим инÑÑÑÑÐ¼ÐµÐ½Ñ ÐºÐ°Ñо veraPDF, ÑÑй каÑо валидаÑоÑиÑе имплеменÑиÑÐ°Ñ Ð¿ÑипокÑиваÑи Ñе, но не иденÑиÑни набоÑи Ð¾Ñ Ð¿Ñавила; когаÑо дваÑа инÑÑÑÑменÑа Ñе ÑазминаваÑ, ÑекÑÑÑÑ Ð½Ð° конÑÑаÑаÑиÑÑа обикновено поÑоÑва конкÑеÑÐ½Ð¸Ñ Ð¿Ð°ÑагÑÐ°Ñ Ð¾Ñ ÑÑандаÑÑа.
ÐÑ Ð²ÑиÑко Ñова пÑоизÑиÑа важен извод за поÑледоваÑелноÑÑÑа. ÐодпиÑванеÑо и поÑÑавÑнеÑо на вÑемеви пеÑÐ°Ñ Ð½Ðµ ÑÑÐ°Ð²Ð°Ñ Ñ ÐµÐ´Ð½Ð¾ пÑеминаване: пÑÑво Ñе запиÑва оÑновниÑÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñ, а Ñлед Ñова оÑделен пÑоÑÐµÑ Ð·Ð° вÑемеви пеÑÐ°Ñ ÑазÑиÑÑва CMS в ÑамкиÑе на запазеноÑо пÑоÑÑÑанÑÑво в /Contents. ÐÑо заÑо ÑедÑÑ Ð·Ð° запазване на байÑове по-гоÑе има Ñолкова голÑмо знаÑение. Ðа вÑÐµÐ¼ÐµÐ²Ð¸Ñ Ð¿ÐµÑÐ°Ñ Ð¸ ÑлоевеÑе за дÑлгоÑÑоÑно валидиÑане, коиÑо Ñе изгÑÐ°Ð¶Ð´Ð°Ñ Ð²ÑÑÑ Ñ Ñази ÑабоÑна ÑÑеда, ÑÑководÑÑвоÑо за PAdES подпиÑване и валидиÑане пÑоÑледÑва подпиÑа Ð¾Ñ Ð±Ð°Ð·Ð¾Ð² до ниво B-LT, а ÑемаÑа за пÑовеÑкаÑа е Ñазгледана по-подÑобно в ÑÑководÑÑвоÑо за PDF/A и PDF/UA пÑовеÑка. ÐÑлнаÑа докÑменÑаÑÐ¸Ñ Ð·Ð° API и пÑобни веÑÑии Ñа налиÑни на пÑодÑкÑоваÑа ÑÑÑаниÑа на PDFlibPas.