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).
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.
Ve své podstatě existují dva druhy kódování: asymetrický (s veřejným klíčem) a symetrické (s tajným klíčem).
$string = sifra_k("TotoJeMojeSifrovanaZprava", 4); $string = sifra_k($string, 6); $string = sifra_k($string, 2); print $string = sifra_k($string, 4);
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.
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ů:
Pokud jde o konstanty, na výběr máte z pěti různých:
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á
Dobrej článek. Jen tak dál. Tak jsem si trochu zavzpomínal a zaprogramoval. Škoda, že dnes už na to nemám čas.
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