Et PDF-tilladelsesflag er ikke en lås. Det er en anmodning, filen retter til, hvad end der åbner den, og en viser står frit for at ignorere det. Netop det faktum afgør, hvordan man bør ræsonnere om alle andre valg på denne side. Reel fortrolighed kommer kun fra ét sted: AES-256-kryptering med en nøgle afledt af en adgangskode, som læseren ikke har. Alt andet, afkrydsningsfelterne "ingen udskrivning" og "ingen kopiering", er politik, som konform software accepterer at overholde, og som fjendtlig software ikke gør. Bland de to lag sammen, og man leverer noget, der føles sikkert i en demo og lækker i felten
HotPDF er en native VCL PDF-komponent til Delphi og C++Builder, og den eksponerer ISO 32000-beskyttelsesmodellen gennem et lille sæt egenskaber. Egenskaberne er lette at sætte. Det svære er at vide, hvilken der giver kryptografisk beskyttelse, og hvilken der blot giver et høfligt forslag, samt at få tildelingsrækkefølgen rigtig, så den kryptering, man har bedt om, rent faktisk er den kryptering, man får
Hvad de to adgangskoder rent faktisk lover
PDF-kryptering definerer to legitimationsoplysninger med hver sin opgave, og at sammenblande dem er den mest almindelige designfejl i kode, der producerer beskyttet output. Brugeradgangskoden styrer dekrypteringen. Uden den, eller ejeradgangskoden, kan en konform læser ikke genskabe filnøglen, og indholdet forbliver kryptografisk ulæseligt. Ejeradgangskoden styrer i stedet tilladelsesindstillingerne: en læser, der modtager ejeradgangskoden, får fuld adgang, uanset hvad begrænsningsflagene siger
Tilladelsesbittene står på svagere grund. Udskrivning, indholdsudtræk, formularudfyldning: hver af dem er et flag, en viser læser og vælger at respektere (ISO 32000-2 §7.6.4). Kryptering beskytter bytes. Tilladelsesflagene instruerer kun konform software, og de gør det efterfølgende. Enhver, der åbner dokumentet med brugeradgangskoden, har allerede det dekrypterede indhold i hukommelsen, så "ingen kopiering" og "ingen udskrivning" betyder noget for en velopdragen viser og intet for en beslutsom en. Byg trusselsmodellen op omkring den linje. Fortroligheden bor i brugeradgangskoden. Tilladelser former, hvad de gængse visere tilbyder, og det er alt, de gør
Konfigurationsrækkefølge: alt før BeginDoc
HotPDF opbygger krypterings-dictionaryen og udleder filnøglen i det øjeblik, BeginDoc kører. Hvad end beskyttelsesegenskaberne indeholder på det tidspunkt, er det, dokumentet får, og at ændre dem bagefter ændrer intet. Den egenskab, der betyder mest her, er CryptKeyLength, som vælger skemaet blandt THPDFKeyType-værdierne k40, k128, aes128 og aes256. Tildel den efter BeginDoc, og man får ingen undtagelse, ingen advarsel, blot en fil, der stille beholdt, hvad den startede med. Den slags stille afvigelse er den værste sort: den består hver eneste lokale test og dukker op måneder senere som et compliance-fund på en kundes skrivebord
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'statement.pdf';
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256; // skal sættes før BeginDoc
Pdf.UserPassword := 'open-secret';
Pdf.OwnerPassword := 'admin-secret';
Pdf.UseAES256R6 := False; // R=5: bredeste viewer-understøttelse
Pdf.BeginDoc;
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(50, 720, 0, 'Account statement, June 2026');
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Adgangskoder er UTF-8 og maksimeret til 127 byte, hvilket er ISO 32000-2-grænsen for AES-256-skemaerne. Hvis din adgangskodepolitik giver dig længere hemmeligheder, så udfør afkortningen selv, på din side, hvor du har kontrol over præcis, hvor snittet lægges. Overlad det til tilfældet, og biblioteket og en fremtidig viser kan være uenige om afskæringen, hvilket giver en fil, der åbner hos dig og afviser den samme adgangskode et andet sted
Revision 5 eller revision 6: én boolean, to økosystemer
UseAES256R6 vælger mellem de to AES-256-håndtryk, og valget har større konsekvenser, end dets boolean-type antyder. Lad den stå på False, og HotPDF skriver revision 5, det AES-256-skema, der kom som en udvidelse til PDF 1.7, og som noget i retning af femten års visere kan åbne. Sæt den til True, og man får revision 6, den hærdede nøgleudledning standardiseret i ISO 32000-2 til PDF 2.0, som lukker en kendt svaghed i, hvordan revision 5 verificerer adgangskoden
Så revision 6 er den kryptografisk bedre historie. Den er også den, der ødelægger ting. En revision 6-fil kræver en viser bygget til PDF 1.7 Extension Level 3 eller PDF 2.0, og en stor del af den software, der er i drift, er hverken det ene eller det andet: records-management-arkiver, indlejrede renderere i andre produkter, forretningsværktøjer, ingen har rørt i årevis. De vil afvise filen fuldstændigt, og de vil gøre det på kundens maskine, aldrig på din. Det praktiske standardvalg er derfor revision 5. Ræk kun efter revision 6, når en sikkerhedspolitik nævner ISO 32000-2 ved revision, og når du rent faktisk har bekræftet, at enhver modtager kan læse den. Under alle omstændigheder, skriv ned, hvilken du valgte og hvorfor, for den næste person, der rører ved denne kode, vil undre sig
De ældre nøgletyper fortjener en sætning, så du ved, at de skal springes over. THPDFKeyType opremser stadig k40, k128 og aes128, men de findes for at gengive historiske arkiver, ikke for at beskytte nye. 40-bit RC4 falder for standardhardware, og 128-bit-skemaerne går forud for de AES-256-revisioner, som enhver nutidig sikkerhedsgennemgang vil forvente. For et dokument, du opretter i 2026, er det reelle spørgsmål kun revision 5 versus revision 6; hvis du finder dig selv ræk efter de gamle typer i et nyt design, er der gået noget galt længere oppe i kæden
Tilladelsesflag uden en åben adgangskode
Ofte er kravet det modsatte af hemmeligholdelse. Alle skal kunne læse dokumentet, men udskrivning eller udtræk skal begrænses. Det udtrykker man med en tom brugeradgangskode og en ikke-tom ejeradgangskode, hvilket PDF kalder open-password-tilstand, og man opremser de operationer, man vil tillade, i ProtectOptions
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.UserPassword := ''; // alle kan åbne filen
Pdf.OwnerPassword := 'rotate-me-quarterly'; // beskytter tilladelsessættet
Pdf.ProtectOptions := [prPrint, prPrint12bit, prExtractContent];
Pdf.BeginDoc;
// ... sideindhold ...
Pdf.EndDoc;
Sættet THPDFProtectOptions afbilder direkte på ISO-tilladelsesbittene: prPrint og prPrint12bit til udskrivning i høj opløsning, prInformationCopy til generel kopiering og udtræk, prExtractContent til udtræk til hjælpeteknologi, plus prModifyStructure, prEditAnnotations, prFillAnnotations og prAssemble. To af dem fortjener en advarsel. Lad prExtractContent stå slået til i næsten enhver profil, du bygger. Det er det bit, en skærmlæser har brug for for at nå teksten, og at slå det fra omdanner stille og roligt en rettighedsbeslutning til en tilgængelighedsfejl, som en person med et handicap rammer ind i, og som du aldrig ser. Den anden fælde er prPrint alene, uden prPrint12bit: adskillige visere reagerer ved at forringe udskriftskvaliteten, og dine brugere vil indberette det som en gengivelsesfejl frem for den tilladelsesindstilling, det faktisk er
Verifikation tager fem minutter og hører hjemme i din release-tjekliste. Åbn et eksempel af hver profil i Acrobat, åbn Dokumentegenskaber, og læs fanen Sikkerhed, som staver algoritmen ud ("AES 256-bit") og lister de tilladte operationer én ad gangen. Åbn derefter den samme fil i den ældste viser, dine kunder rent faktisk kører, ikke den nyeste på din egen maskine. Den anden åbning er den billige forsikring mod, at en revision 6-fil sejler gennem udviklingen og dør hos en kunde, der aldrig opgraderede
Fjernelse af beskyttelse fra eksisterende filer
Dekryptering kører den samme egenskabsmodel baglæns. Indlæs dokumentet med en gyldig legitimation, slå beskyttelsen fra, og gem resultatet uden den
var
Pdf: THotPDF;
PageCount: Integer;
begin
Pdf := THotPDF.Create(nil);
try
PageCount := Pdf.LoadFromFile('encrypted.pdf', 'open-secret');
if PageCount > 0 then
begin
Pdf.ActivateProtection := False; // fjern kryptering ved gemning
Pdf.SaveLoadedDocument('plain.pdf');
end;
finally
Pdf.Free;
end;
end;
Den rute parser hele dokumentet ind i hukommelsen, hvilket er fint for almindelige filer og spild af ressourcer for enorme. Når input løber op i hundredvis af megabyte, er DecryptFile den billigere mulighed: den dekrypterer under en kopiering på filniveau og tager en direkte AES-256-omskrivningssti, der springer opbygningen af det fulde objekttræ over, når input tillader det. Det er en del af Direct File API'et, der dækkes i følgeartiklen om at behandle store PDF'er fra Delphi
Begrænsninger, der spiller sammen med kryptering
To grænser er værd at kende, før man designer omkring kryptering frem for bagefter. Den første er arkivkonformitet. ISO 19005 forbyder kryptering i PDF/A, så enhver workflow, der krypterer et dokument og samtidig hævder PDF/A-konformitet, er selvmodsigende i sin konstruktion; HotPDF vil ikke lade dig have begge dele i én fil. Når man reelt har brug for begge dele, er svaret to artefakter: en krypteret kopi til distribution og en separat ukrypteret kopi til arkivet
Den anden grænse er hårdere. PDF-kryptering har ingen deponering og ingen gendannelse. Mister man brugeradgangskoden til en R5- eller R6-fil, er ens muligheder brute force eller at give op. Behandl derfor ejer- og brugerhemmeligheder på samme måde, som man behandler enhver produktionslegitimation. Generér dem, opbevar dem i et vault, rotér dem efter en plan. Det ene, man aldrig må gøre, er at hardkode dem som konstanter i en unit, hvor de kører lige ind i versionsstyringen og sidder i enhver udviklers arbejdskopi for evigt
Én sidste refleks er værd at opbygge. At ændre beskyttelsen på en fil, man ikke selv har oprettet, er det samme maskineri som dekryptering, ikke en separat funktion: indlæs den med dens adgangskode via LoadFromFile, redigér ProtectOptions eller adgangskoderne på stedet, og skriv den tilbage med SaveLoadedDocument. Kan man dekryptere en fil, kan man også ændre dens tilladelser, og koden ser næsten identisk ud med eksemplet ovenfor
Beskyttelsesegenskaberne, der er vist her, er en del af den almindelige HotPDF Delphi Component til Delphi og C++Builder; produktsiden indeholder den fulde krypteringsreference, herunder den komplette opremsning af tilladelser