Vodoznak a štruktúra QR kódu
Ochrana dokumentov je jedna zo základných vecí, ktoré je nutné pokryť a riešiť v našom projekte. Cieľom je, aby sme vo veľkej miere eliminovali neoprávnené kopírovanie, rozposielanie chránených PDF dokumentov. Spôsob, aký budeme aplikovať v našom PDF vieweri je použitie vodoznakom ("watermarks") na každej strane dokumentu pomocou unikátneho QR kódu. Zároveň chceme docieliť to, aby tento QR kód nebol v rámci strany dokumentu invazívny a aby nevzbudzoval zbytočnú pozornosť používateľa. V prípade, ak by sa predsa používateľ rozhodol napríklad pomocou QR kode readera naskenovať daný QR kód, informácie z neho budu preňho z prvotného pohľadu nezaujímavé.
Štruktúra QR kódu a jeho dáta
Bude sa skladať z podstatných dát, ktoré v prípade neopráveného nakladania s PDF dokumentom slúžia na jednoznačnú identifikáciu. Typ dát, ktoré použijeme je inšpirovaný a nadväzuje na databázový model Evil Flowers.
id- identifikátor dokumentu/akvizície (knihy, zbierky a pod.)creator_id- identifikátor používateľa, pre ktorého je dokument vygenerovaný. V prípade neoprávneného rozosielania vieme jednoznačne zistiť, ktorý používateľ dokument rozposlal alebo robil úkony, ktoré nie sú v súlade s pravidlami.title- názov dokumentuis_public- true/false hodnota obsahujúca infomáciu, či je dokument Open Access alebo niecreated_at- časová pečiatka vo forme dátumu, kedy bol dokument pre používateľa vygenerovaný.
Spôsob generovania watermarku
V tejto kapitole prejdeme samotný spôsob akým štýlom budeme QR generovať s možnosťou spätného procesu v prípade potreby.
JSON formát
Ukladať a pracovať s dátami v JSON formáte v komnbinácii s QR kódom sa javí ako vhodná voľba. Potrebné dáta si preto budete reprezentovať v JSON formáte a ukážka môže vyzerať nasledovane:
{
"id": 99565656,
"user_id": 564521654,
"acquisition_id": 989556,
"title": "Nazov knihy",
"is_public": true,
"created_at": "2022-11-191-15:08:29.9072"
}
Generovanie
Pokiaľ máme pripravené dáta, môžeme v Pythone veľmi jednoducho vytvoriť/generovať unikátny QR kód, ktorý obsahuje práve naše dáta. Ukážka jednoduchého kódu, ktorý vygeneruje QR kód:
Inštalácia knižnice qrcode pre QR kód:
$ pip install qrcode
Zdrojový kód jednoduchého generovania QR kódu:
import qrcode
import json
# Origin data object
data = {
"id": 99565656,
"user_id": 564521654,
"acquisition_id": 989556,
"title": "Nazov knihy",
"is_public": True,
"created_at": "2022-11-191-15:08:29.9072"
}
# Instance of QR code class
qr = qrcode.QRCode(version = 1,
box_size = 5,
border = 5)
# converting into JSON:
dataJSON = json.dumps(data)
qr.add_data(dataJSON)
qr.make(fit = True)
img = qr.make_image(fill_color = 'black',
back_color = 'white')
img.save('watermark_qrcode_example.png')
Výstupom je samotný QR kód:
Spätná interpretácia
Z QR kódu pri spätnej interpretácii vieme vyčítať informácie. Tento prístup je vhodný v scenári, keď by sa stal incident, že chránený vygenerovaný PDF dokument s vodoznakom v podobe QR kódu je neoprávnene kopírovaný, rozposielaný. Pri dekódovaní QR sa nám zobrazia pôvodné informácie a vieme identifikovať používateľa, ktorý sa tohto činu dopustil, tiež aj o aký dokument sa jednalo a kedy bol tento dokument pôvodne pre používateľa generovaný.
Príklad, kedy vyššie zobrazený QR sme spätne dekódovali a dostanene pôvodné informácie:
Šifrovanie
V našom riešení pomocou QR kódov je vhodné použiť aj šifrovanie, ktoré by pôvodné JSON dáta zašifrovalo a až potom by sme generovali QR kód. Následne ak by sme potrebovali získať informácie o používateľovi, dokumente a čase, tak by sme z QR kódu získali zašifrované dáta, pomocou kľuča by sa vykonalo dešifrovanie a dostali by sme sa k pôvodným dátam. Toto by nám zabezpečilo ešte väčšiu "nezaujímavosť" pre bežného používateľa, ktorý by chcel pomocou QR code readera vyskúšať, aký výstup mu QR kód poskytune. Výstupom by pre používateľa boli iba rôzne znaky, ktoré by pre neho neboli zaujímavé, čo je presne stav, ktorý chceme dosiahnuť.
cryptography
Na šifrovanie môžeme použiť knižnicu cryptography, ktorá v sebe obsahuje šifrovacie štandardy. Na jednoduchom príklade je vysvetlený celý proces šifrovania a dešifrovania údajov, ktoré budú obsahovať QR kód.
Nainštalovanie knižnice:
$ pip install cryptography
Pôvodné dáta a importy knižníc:
from cryptography.fernet import Fernet
import json
# Origin data object
data = {
"id": 99565656,
"user_id": 564521654,
"acquisition_id": 989556,
"title": "Nazov knihy",
"is_public": True,
"created_at": "2022-11-191-15:08:29.9072"
}
dataJSON = json.dumps(data)
Vygenerujeme kľúč, ktorý použijeme pre šifrovanie a následné dešifrovanie (použili sme Fernet, ale môžeme použiť aj iné metódy šifrovania). Následne dostaneme inštanciu Fernet classy s klúčom.
key = Fernet.generate_key()
fernet = Fernet(key)
V tomto bloku vykonáme šifrovanie a dešifrovanie. Potom porovnáme výstupy a vidíme, že sme naše dáta o dokumentoch v JSON formáte sú úspešne zašifrované a tiež sme dokázali vykonať aj spätnú interpretáciu, ktorá je vidieť v konzoli.
encryptedData = fernet.encrypt(dataJSON.encode())
decryptedData = fernet.decrypt(encryptedData).decode()
print("Original Data: ", dataJSON)
print("Encrypted Data: ", encryptedData)
print("Decrypted Data: ", decryptedData)
Výstup z konzoli:
Original Data: {"id": 99565656, "user_id": 564521654, "acquisition_id": 989556, "title": "Nazov knihy","is_public": true, "created_at": "2022-11-191-15:08:29.9072"}
Encrypted Data: b'gAAAAABje9qgbm-ST3bQeezKsujFDpOWRPn4N8NKXK4l0bNwHIijy35vrV89a-s2HzxU7otApaiYPOnURtCw_zcB_XD7IsebQxFUmACx7ULWdjaByVZ0bEMTfWQMiIEzphwnL116f_4j...'
Decrypted Data: {"id": 99565656, "user_id": 564521654, "acquisition_id": 989556, "title": "Nazov knihy","is_public": true, "created_at": "2022-11-191-15:08:29.9072"}
Vizualizácia vodoznaku v dokumente
Nami navrhnutý vodoznak má nasledovné vlastnosti:
- malá veľkosť
- nepriehladnosť
- nezasahuje do textu dokumentu
Ukážka strany PDF dokumentu:
Pre vylepšenie ochrany dokumentov by bolo možné aplikovať generovanie QR kódu takým štýlom, že na každej strane by sa nachádzal na inej pozícií, čo by mohlo stažiť a znechutiť používateľovi, aby rozposielal a prekopirovával strany.
V našom projekte budeme zobrazovať menší QR kód, ktorý nebude zasahovať do textu. Z hľadiska vizuálneho aj implementačného je to podľa nášho uváženia vhodné riešenie.
Autor: Jakub Sorád