Nikomu to neříkejte!!!

Všichni víme, že jednou z největších slabin DBF souborů je možnost podívat se bez jakýkoliv omezení do dat, takže o utajení si můžeme pouze nechat zdát. A což teprve když chceme někam uložit heslo, text… Pokusy o šifrování tím, že místo hesel uložíme hodnotu funkce SYS(2007,Heslo), nebo tím, že zašifrujeme data pomocí BITXOR(…), nelze bohužel brát příliš vážně.

Přímo ve VFP máme k dispozici ve FFC (FoxPro Foundation Classes) třídy pro použití Crypto API (tj. použití šifrování přímo z Windows). V tom případě si ale musíte dát pozor na to, že různé verze Windows mají jako defaultní různé verze Crypto Provideru (např. je rozdíl mezi Windows 2000 a Windows XP), takže musíte správně nastavit vlastnost cprovidername u třídy _cryptoapi. Osobně vidím nerad, když můj program tak silně závisí na okolním prostředí. Měli bychom tedy vzít nějakou skutečně dobrou šifru (= ověřenou v praxi) a implementovat ji ve VFP. Asi si říkáte, že VFP není právě nejvhodnější na implementaci šifrování, ale snad Vás přesvědčím, že to není pravda.

Jako šifru jsem si vybral aRCfour. Její historie je zajímavá. Na počátku byla úsoěšná ( a hojně používaná) šifra RC4 firmy "RSA Data Security, Inc.". Její jméno je patentováno, ale algoritmus byl utajen a patentován nebyl. V roce 1994 nějaký anonym poslal na internet zdrojový kód tohoto algoritmu. Nikdo neví , jestli to byl nebo nebyl původní (a správný) algoritmus, ale generoval stejný výsledek jako původní šifra RC4. Vzhledem k oblíbenosti šifry RC4 se začal rychle používat. Nakonec se z něj vyvinul nový standard (používá se například pro SSL při zabezpečeném přenosu přes internet a pod.) Jenom se mu nesmí říkat RC4, proto se používají názvy jako aRCfour…

Pro implementaci je nejlépe použít normu, která je ke stažení na příklad na adrese: http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt

Komentáře v textu obsahují jednotlivé paragrafy normy, jména proměnných jsem zvolil stejná jako v normě:

FUNCTION aRC4(PlainTxt, Key)
LOCAL KeyLen, i, j, Temp, Cipher, lnOff, T, K
#DEFINE ArrOff 1
* 3.1 Key Setup
*    1.

LOCAL ARRAY S[256], S2[256]
KeyLen = LEN(Key)
*    2.
FOR i = 0 TO 255
    S[i+ArrOff] = i
    *    3.
    S2[i+ArrOff] = ASC(SUBSTR(Key, MOD(i,KeyLen)+ArrOff, 1))
ENDFOR
*    4.
j = 0
FOR i = 0 TO 255
    j = MOD(j+S[i+ArrOff]+S2[i+ArrOff],256)
    Temp = S[i+ArrOff]
    S[i+ArrOff] = S[J+ArrOff]
    S[j+ArrOff] = Temp
ENDFOR
* 3.2 Encryption/Decryption
STORE 0 TO i, j
Cipher=""
FOR lnOff = 1  TO LEN(PlainTxt)
    i = MOD(i + 1, 256)
    j = MOD(j + S[j+ArrOff], 256)
    Temp = S[i+ArrOff]
    S[i+ArrOff] = S[j+ArrOff]
    S[j+ArrOff] = Temp
    T = MOD(S[i+ArrOff] + S[j+ArrOff],256)
    K = S[T+ArrOff]
    Cipher = Cipher + CHR(BITXOR(K, ASC(SUBSTR(PlainTxt, lnOff, 1))))
ENDFOR
RETURN Cipher

A jak tuto šifru použijeme? Jednoduše. Stejná procedura se použije pro zašifrování textu i pro jeho zpětné odšifrování. Šifru otestujeme následujícím jednoduchým programem:

Txt   = REPLICATE("pokusný text", 100)
Heslo = "pokusné heslo"
ZasifrovanyTxt = aRC4(Txt,Heslo) 
OdifrovanyTxt = aRC4(ZasifrovanyTxt,Heslo) 

?"Test dopadl "+IIF(OdifrovanyTxt==Txt,"dobře :)","špatně :(")

Tato implemementace korektně pracuje i s takzvanými "testovacími vektory", čímž je zaručena kompatibilita s ostatními implementacemi. Ve skutečnosti bychom si samozřejmně uložili zašifrovaný text do DBF, na heslo se zeptali uživatele a pak provedli odšifrování. Vašim nápadům se meze nekladou. Jen ať nám někdo zkusí řící, že VFP neumí znepřístupnit data ;-)! Poslední poznámka: pro ukládání hesel je výhodnější ukládat jejich "hash", než ukládat zašifrovaná hesla. Jako "hash" se používá například SHA1, ale zdrojový kód těchto hashovacích funkcí ve VFP je příliš dlouhý pro tento krátký článek.

Zdraví vás
Milan Kosina, kosina@vol.cz