Hledat
Přihlásit se
  • Věda a technika
  • Herní doupě
  • Tipy pro PC
  • IT Byznys
  • Mobily
  • Počítače
  • Počítače
  • Témata
  • Poradna
  • Diskuzní fórum
  • Video
  • Bazar
  • Blogy
  • MĚŘENÍ RYCHLOSTI
  • RSS
  • Facebook Twitter Google+ YouTube
  • Hardware
  • Software
  • Počítače
  • Notebooky
  • Služby na webu
  • Apple
  • Google
  • Microsoft
  • Seznam
  • Tiskové zprávy
Další témata
  • Týden Živě
  • Zprávy Živě
  • Testy
  • Pitvy
Všechna videa
X

Doporučit článek

Vaše jméno:

Váš e-mail:

E-mail adresáta:

Komentář:

kontrolní kód

Odeslat

Blogy Živě » Zaachi blog

Zaachi blog

Nový blog na adrese Blog.zive.cz
 

Kryptografie, kódování dat

30. 8. 2008, z@chi

Kryptografie, neboli šifrování dat, je nauka o transformování dat do podoby, která je čitelná jenom s určitou znalostí. Slovo Kryptografie pochází z řečtiny – kryptós (je skrytý) a gráphein (psát).

Pojem kryptografie

Na úvod si řekneme něco o pojmu kryptografie:

Kryptografie, neboli šifrování dat, je nauka o transformování dat do podoby, která je čitelná jenom s určitou znalostí. Slovo Kryptografie pochází z řečtiny – kryptós (je skrytý) a gráphein (psát).

Často je pojem zaměňován, nebo používán, pro vědu o šifrách – kryptologii.

Kryptografie se vyvíjí již celá staletí, nebo tisíciletí. V historii postupně vznikali lepší a důmyslnější šifry, které často ovlivnili mnohé historické události (zejména, jednalo li se o utajování a vyzrazování informací).

Taková jednoduchá šifra by mohla vypadat takto:

$abeceda = 'abcdefghijklmnopqrstuvwxyz';
function sifra_k($str, $posunuti)
{
global $abeceda;
$str = strtolower($str);
for($i = 0; $i < strlen($str); $i++)
{
    $new_pos = strpos($abeceda, $str[$i]) + intval($posunuti);
    if($new_pos >= ($len = strlen($abeceda))){
    $new_pos = $new_pos - $len;
    }
    $new_str .= $abeceda[$new_pos];
}
return $new_str;
}
print $string = sifra_k("TotoJeMojeSifrovanaZprava", 4);

kde jsme jenom posunuli znaky v abecedě. Nicméně na výstupu dostaneme řetězec
xsxsniqsniwmjvszeredtveze, který se zdrojové zprávě nepodobá ani přinejmenším.

Takový je význam šifer a šifrování.

V PHP se kódování využívá nejčastěji pro zakódování informací, které chceme ochránit (například platy zaměstnanců, a podobné citlivé informace), ale může se používat i například pro generování kontrolních součtů souborů.

Použití kódování dat nám zajišťuje vyšší bezpečnost, ale může způsobit i pocit falešného bezpečí, na to musíme dávat pozor.

Většina funkcí pro kódování dat v PHP je v knihovnách mcrypt a mhash.

Kódování

Ve své podstatě existují dva druhy kódování: asymetrický (s veřejným klíčem) a symetrické (s tajným klíčem).

  • symetrická kryptografie: při symetrickém kódování je potřeba tzv. klíče. Klíč je určitá hodnota (informace), podle niž dojde k zakódování textu. V příkladu, který zde byl uveden, je takový klíč číslo 4. Klíč může být ovšem i větších rozměrů: 4 -> 6 -> 2. Volání by potom vypadalo takto:
$string = sifra_k("TotoJeMojeSifrovanaZprava", 4);
$string = sifra_k($string, 6);
$string = sifra_k($string, 2);
print $string = sifra_k($string, 4);
  • pokud chceme potom text rozkódovat, potřebujeme stejný klíč a výsledný zašifrovaný řetězec. Jinak bychom neměli být schopni z šifrovaného textu dostat zdrojový text. Výhodou tohoto šifrování je její rychlost a využívá se pro šifrování dat, která již dále neputují, například dokumenty na svém počítači. Jako nevýhodu můžeme uvést klíč, který je potřeba pro výměnu takových informací.
    Pokud bychom chtěli s někým komunikovat, musíme mu nějak sdělit náš klíč.
  • asymetrická kryptografie: asymetrická kryptografie se od symetrické liší právě použitím klíčů. Používá totiž jeden klíč pro zašifrování a jiný klíč pro dešifrování. Takové dva klíče se nazývají keypair. Klíč pomocí něhož se šifruje se potom nazývá veřejný (public) klíč a klíči pro dešifrování říkáme soukromý (private) klíč. Při práci máme k dispozici dva klíče, přičemž veřejný klíč znají všichni, kdo s námi chtějí tajně komunikovat a soukromý klíč znáte jenom vy. Tím pádem odpadá problém při předávání klíče, ale můžeme jej v klidu rozesílat internetem. Útočník, který by jej odchytil by získal jenom veřejná všude známý klíč, který by mu k ničemu nebyl.

Pokud budete chtít využívat šifrování v PHP, budete potřebovat knihovnu mcrypt nebo mhash. Tyto dvě knihovny obsahují celou spoustu algoritmů, ze kterých si můžete vybrat pro vás ten nejlepší. Uvedu příklad z knihovny mcrypt.

  • MCRYPT_3DES
  • MCRYPT_DES
  • MCRYPT_TripleDES
  • MCRYPT_ENIGMA
  • MCRYPT_IDEA
  • MCRYPT_RIJNDAEL_256
  • MCRYPT_RC6
  • MCRYPT_SAFER128
  • MCRYPT_SERPENT_256
  • MCRYPT_THREEWAY
  • MCRYPT_TWOFISH256

a mnohé další.

Bohužel mnohé z těchto algoritmů nejsou dostatečně bezpečné, proto je důležité si správně vybrat. Míra zabezpečení závisí taky na velikosti klíče, který je použit. Uvědomte si, že klíč o velikosti 43 bitů je dvakrát tak účinný a trvalo by dvojnásobnou dobu jej prolomit útokem typu Brute Force (klíč má dvojnásobný počet kombinací) než klíč s velikostí 42 bitů.

V PHP má kódování uplatnění hlavně při předávání informací, ať už mezi serverem a klientem, nebo mezi servery. Míra důležitosti informace by se neměla podceňovat.

K použití algoritmů můžete zase využít funkci mcrypt. Před použitím musíte ovšem znát algoritmus kódování, který chcete použít, režim, ve kterém chcete kódovat, a konstantu, která udává co chcete s daným řetězcem dělat.

Jako algoritmus uvádíme název algoritmu uvedený v knihovně mcrypt.
Režim, je způsob, který se bude brát v ohled při kódování. U funkce mcrypt můžete použít několik různých režimů:

  • EBC: tento režim se používá nejčastěji pro kódování malých objemů dat. Tento způsob ale není moc bezpečný.
  • CBC: univerzální režim. Používá se pro kódování jak malých dat, tak i větších souborů. Je mnohem bezpečnější než EBC.
  • CBF: pro datové bitové proudy.
  • OFB: režim je podobný režimu CBF, ale může být použita v aplikacích, kde nesmí být tolerovány chyby.
  • NOFB: je režim podobný OFB, ale je bezpečnější.
  • STREAM: je speciální režim.

Pokud jde o konstanty, na výběr máte z pěti různých:

  • MCRYPT_ENCRYPT
  • MCRYPT_DECRYPT
  • MCRYPT_DEV_RANDOM
  • MCRYPT_DEV_UNRANDOM
  • MCRYPT_RAND

Každá z nic má jiné využití.

A výsledná funkce může vypadat takto:

$data = "data pro zakodovani.";
print $kodovana_data = mcrypt_ecb(MCRYPT_TRIPLEDES, "klic", $data, MCRYPT_ENCRYPT);

Pokud tento skript spustíme, dostaneme jenom směsici nesmyslných znaků, které nedávání smysl. Jsou to binární data, které funkce mcrypt vrací. Pro normální použítí, například í v SESSION, nebo COOKIES proměnných je ovšem potřeba data ještě upravit a nepoužívat jejich binární podobu. Můžeme použít funkci bin2hex, nebo klidně třeba funkci urlencode, abychom převedli binární znaky do podoby, kterou je schopen server zpracovávat a předávat.

print  bin2hex($kodovana_data);

Pro dekódování tímto způsobem musíme použít stejný režim jako pro kódování, ale s konstantou MCRYPT_DECRYPT:

$kodovana_data = mcrypt_ecb(MCRYPT_TRIPLEDES, "klic", $kodovana_data, MCRYPT_DECRYPT);
print $kodovana_data;

Podle nastavení serveru můžete dostat na výstupu warning:

Warning: mcrypt_ecb() [function.mcrypt-ecb]: Attempt to use an empty IV, which is NOT recommend in /home/www/zaachi.com/subdomains/pokus/index.phpon line 4

Parser vás varuje, že jste použili prázdný Inicializační Vektor (IV), což nedoporučuje.
Inicializační vektor se generuje z určitých vstupních dat a pokud nemá druhá strana stejný inicializační vektor, nemělo by se jí podařit data dekódovat, takže se jedná o další možné zabezpečení.

Pokud bychom chtěli vytvořit skript pro kódování s inicializačním vektorem, mohl by vypadat nějak takto:

Vytvoříme třídu, která se bude používat jak pro kódování, tak dekódování:

class crypt_str
{
    public $key = NULL;
    public $algoritmus = NULL;
    public $rezim = NULL; 

    function __construct($key, $algoritmus = 'des', $rezim = 'cbc'){
        if(($this->key = $key) == NULL)
            return 0;
        $this->algoritmus = $algoritmus;
        $this->rezim = $rezim;
    } 

    function hash_key(){
     $this->key = sha1($this->key);
    } 

    function encrypt($string,$key) {
        //nejprve otevřeme modul algoritmu pro jeho použití
        //parametry: algoritmus, knihovna algoritmu, režim, knihovna režimu
        $moopen = mcrypt_module_open($this->algoritmus, '',$this->rezim, '');
        //funkce mcrypt_enc_get_key_size vrátí maximální podporovanou délku klíče
        //nastavíme tedy klíč na jeho maximální možnou velikost
        $this->key = substr($this->key, 0, mcrypt_enc_get_key_size($moopen));
        //nastavíme velikost IV (inicializační vektor)
        $iv_size = mcrypt_enc_get_iv_size($moopen);
        //a vytvoříme inicializační vektor - IV
        //MCRYPT_DEV_RANDOM čte nádohná data z dev/random
        $iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_RANDOM);
        //inicializujeme všechny buffery potřebné pro encription
        if (mcrypt_generic_init($moopen, $this->key, $iv) != -1) {
            //závisle na algoritmu kódujeme data
            $c_str = mcrypt_generic($moopen, $string);
            //deinicializujeme všechny buffery
            mcrypt_generic_deinit($moopen);
            //uzavřeme modul
            mcrypt_module_close($moopen);
            $c_str = $iv.$c_str;
            //vrátíme řetězec v binárním tvaru.
            return $c_str;
        }
        else return -1;
    } 

    function decrypt($string,$key) {
        //zase nejprve otevřeme modul
        $moopen = mcrypt_module_open($this->algoritmus, '',$this->rezim, '');
        //vytvoříme maximálně velký klíč pro použitý algoritmus
        $this->key = substr($this->key, 0, mcrypt_enc_get_key_size($moopen));
        //nastavíme velikost IV
        $iv_size = mcrypt_enc_get_iv_size($moopen);
        //musíme nastavit IV na maximální velikost
        $iv = substr($string,0,$iv_size);
        //z řetězce vrátíme pouze jenom maximální velikost
        $string = substr($string,$iv_size);
        //inicializujeme buffers
        if (mcrypt_generic_init($moopen, $this->key, $iv) != -1) {
            //decryptujeme data závisle na modulu
            $c_str = mdecrypt_generic($moopen, $string);
            //deinicializujeme buffers
            mcrypt_generic_deinit($moopen);
            //uzavřeme modul
            mcrypt_module_close($moopen);
            return $c_str;
        }
        else return -1;
    }
}

Ve volání konstruktoru se nejprve nastaví hodnoty jako je: režim kódování, algoritmus, pomocí něhož se kóduje a potřebný klíč.

Po vytvoření nové instance třídy můžeme ještě vytvořit hash klíče, pro větší bezpečnost, a zavolat příslušnou obslužnou funkci, přičemž máme na výběr ze dvou: encrypt (pro zakódování) a decrypt (pro dekódování).

Takové volání potom může vypadat následovně:

$data = "Data pro zakódování";
$key = "klic"; 

//vytvoříme novou instanci třídy
$use = new crypt_str("klic");
//pro větši bezpečnost můžeme vytvořit hash klíče
$use->hash_key();
//a pro ověření spustíme:
print $use->decrypt($use->encrypt($data, $key), $key);

Bohužel na některých serverech nemusí fungovat konstanta MCRYPT_DEV_RANDOM, ale budete ji muset nahradit konstantou MCRYPT_RAND. Před jejím použitím musíte ale nastartovat generátor náhodných čísel:

srand((double) microtime() * 1000000);

a při vytváření inicializačního vektoru je nutno nahradit konstantu MCRYPT_DEV_RANDOM konstantou MCRYPT_RAND:

$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

Je nutné si uvědomit, že pokud má útočník přístup na server, má přístup i k vašemu klíči. Pokud tedy vytváříte inicializační vektor, pak mu alespoň přiděláte trochu práce.

Pokud chcete svá data opravdu zabezpečit tak aby se k nim opravdu nikdo nedostal, pak vám nezůstane žádná jiná možnost, než používat vlastní server, ke kterému nemá kromě vás nikdo jiný přístup, nebo data nevystavovat na internetu. Až pak budou data možná v bezpečí. Pokud budete využívat cizí hosting, nemůžete mít nikdy stoprocentní jistotu, že vaše data nikdo nečte.

Štítky: asymetrická, Bezpečnost, kodovani, kryptografie, kryptologie, PHP, symetrická


Publikováno v rubrice Bezpečnost, PHP. Reakce v diskuzi lze sledovat prostřednictvím RSS 2.0. Můžete přidat komentář, nebo se na článek odkázat ze svého webu.

« Sláva spamerům, čest …
MHASH_CRC32 »
 

Komentáře v diskuzi

1.  Krypton(89.102.203.xxx)   31. 8. 2008, 22:40

Dobrej článek. Jen tak dál. Tak jsem si trochu zavzpomínal a zaprogramoval. Škoda, že dnes už na to nemám čas.

Přidat komentář

*
Opište prosím text z obrázku.
Anti-Spam Image

Zaachi blog využívá WordPress MU a běží na Blog.zive.cz. Vytvořte si svůj vlastní blog
Sledování přes RSS: články a komentáře



  • Kategorie

    • Algoritmy (4)
    • Bezpečnost (7)
    • hardware (4)
    • Java (7)
    • Mimochodem (9)
    • MySQL (2)
    • OpenGL (4)
    • PHP (23)
    • software (6)
    • technologie (8)
  • Poslední příspěvky

    • Java: parsování HTML
    • Debian: když vám server nakyne
    • Google aktualizoval PageRank!
    • Jak se učíte programovat?
    • VirtualBox: jak přežít více systémů
  • Štítky

    3g Algoritmy apple autorizace Bezpečnost c++ datum eclipse gd gd2 google grafy graphs hash http https internet iphone Java javascript kamera knihovna kodovani lamp library linux mlha MySQL nusphere OpenGL operační systém optimalizace PHP phped plynulá změna pohyb popup request server slovník twitter visual studio window windows řazení
  • Kalendář

    Srpen 2008
    P Ú S Č P S N
    « Čvc   Zář »
     123
    45678910
    11121314151617
    18192021222324
    25262728293031
  • Seznam odkazů

    • Zaachi.com
  • Administrace

    • Přihlásit se


Předplatné Computer

Aktuální číslo časopisu Computer
  • Testy nejnovějších produktů na českém trhu.
  • Informace ze světa internetu i bezpečnosti.
  • Plné verze programů zdarma pro všechny čtenáře.
Archiv Předplatné
Elektronické předplatné Tištěné předplatné