Avatar
Matěj Strnad:20. května 19:37

Existuje nějaká jednoduchá možnost šifrování a pak i dešifrování textu v PHP. (chápu hašování i poravnání hesel ale nejde dešifrovat) Děkuji za odpověd :)

Odpovědět 20. května 19:37
Ty vaše internety!
Avatar

Člen
Avatar
 
Nahoru Odpovědět 20. května 19:48
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na Matěj Strnad
Petr Čech:20. května 19:50

Jaké šifrování? Symetrické (jeden klíč), asymetrické (veřejný a soukromý klíč)?
Pokud nerozumíš šifrování, doporučoval bych si to nejdříve důkladně nastudovat, protože se tam strašně snadno udělají kritické chyby, když člověk neví naprosto přesně, co dělá - i třeba pokud se použije silná šifra.

Nahoru Odpovědět 20. května 19:50
the cake is a lie
Avatar
Matěj Strnad:20. května 19:56

Symetrické šifrování :)

Nahoru Odpovědět 20. května 19:56
Ty vaše internety!
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na
Petr Čech:20. května 20:00

Úchvatné, něco takového už jsem dlouho nepotkal. Všechny řádky kromě

$output = false;
$encrypt_method = "AES-256-CBC";

jsou fatálně špatně a přidávají bezpečnostní slabinu. Ano, včetně deklarací proměnných $secret_key a $secret_iv.
Ano, bude to zdánlivě fungovat, ale je to extrémně nebezpečné.

Přesně to je důvod, proč je třeba si bezpečnost nejdříve pečlivě nastudovat předtím, než to člověk použije ;) .

Nahoru Odpovědět 20. května 20:00
the cake is a lie
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na Matěj Strnad
Petr Čech:20. května 20:02

A čím chceš šifrovat? Uživatelským heslem, náhodně vygenerovaným klíčem?
Možná víc rozepiš celý ten tvůj plán, upřímně podezírám, že bude mít bezpečnostní problémy...

Nahoru Odpovědět 20. května 20:02
the cake is a lie
Avatar
Matěj Strnad:20. května 20:06

Uživatel by zadal heslo a text. Heslo by se zahešovalo a to by byl klíč, a tím klíčem by se zašifroval ten text. Dešifrování by probíhalo stejně. :)

Nahoru Odpovědět 20. května 20:06
Ty vaše internety!
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Matěj Strnad
Martin Dráb:20. května 20:30

Šifrování by mohlo vypadat cca takto:

$encrypt_method = "AES-256-CBC";
$key = hash('sha256', $heslo. $salt);
$iv = <náhodně generovaných 16 bajtů>;
 $output = openssl_encrypt($text, $encrypt_method, $key, 0, $iv);

Dešifrování bys z toho měl být schopen odvodit. Je třeba z hesla derivovat klíč (jako při šifrování), vzít IV z šifrového textu a vše vhodit do openssl_decrypt. Alespoň taková je myšlenka. Salt je zde náhodná hodnota, kterou uživateli přidělíš např. při jeho registraci. Cílem je, aby útočník nemohl tak snadno odvodit klíč jen proto, že si uživatel dal heslo 123456.

https://gist.github.com/…0fa533f4ad94

Ano, tohle je takový velmi školní příklad použití šifrování. Konkrétně:

  • klíč bys neměl nikdy definovat přímo v kódu, pokud je tvým účelem utajení,
  • inicializační vektor (IV) bys měl při každém šifrování generovat náhodně, dvě zprávy by nikdy neměly být šifrovány se stejným IV (v tomto případě by to asi nebyl až tak velký průšvih, protože by útočník maximálně poznal, že posíláš zprávu se stejným obsahem... ale u některých schémat tímto opomenutím útočníkovi dovolíš spočítat klíč, a/nebo zprávu dešifrovat).
  • nevím, zda openssl_encrypt přidává inicializační vektor k šifrované zprávě. Pokud ne, měl bys to udělat.
  • inicializační vektor není žádné tajemství, tedy nemá smysl jej nazývat secret. Kdokoliv uvidí zašifrovanou zprávu, dozví se i IV.
Editováno 20. května 20:33
Akceptované řešení
+20 Zkušeností
Řešení problému
Nahoru Odpovědět  +1 20. května 20:30
2 + 2 = 5 for extremely large values of 2
Avatar
Matěj Strnad:20. května 21:27

Jak mám generovat:

$iv

?
Kolik písmen je 16 bitů? :)

Editováno 20. května 21:28
Nahoru Odpovědět 20. května 21:27
Ty vaše internety!
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Matěj Strnad
Martin Dráb:20. května 22:02

Zdá se, že pro PHP 7 pro tento případ existuje funkce **random_bytes **.
http://php.net/…om-bytes.php

Pokud pro tebe není dostupná, asi by stačilo nové IV generovat nějak takto:

$iv = hash('sha256', $old_iv. $salt);

Princip je podobný jako v případě derivace klíče z hesla, jen nesmíš zapomenout na to, že SHA256 ti dává 256bitový = 32bajtový hash, přičemž ty potřebuješ jen 16 bajtů pro IV (např. 16 prvních bajtů toho hashe).

Kolik písmen je 16 bitů?

Jelikož má AES bloky velké 128 bitů (16 bajtů) a vzhledem k tomu, jak vypadá mód CBC, musí být inicializační vektor dlouhý 16 bajtů.

Jelikož nejsem PHPkař, nevím, v jakém formátu openssl_encrypt akceptuje IV. Pokud by jej brala jako hexadecimální řetězec (každý byte kódovaný dvěma znaky), musel bys generovat 32znakový řetězec. Pokud IV bere přímo, stačil by 16znakový. Ale ta funkce random_bytes přímo generuje bajty, takže pro vygenerování správně dlouhého IV zavoláš

$iv = random_bytes(16);
Nahoru Odpovědět  +1 20. května 22:02
2 + 2 = 5 for extremely large values of 2
Avatar
Matěj Strnad:21. května 7:23

Pro rozšifrování je potřeba stejný IV ?

Nahoru Odpovědět 21. května 7:23
Ty vaše internety!
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21. května 7:50
php.net/openssl_encrypt

Example 1

Example #1 AES Authenticated Encryption in GCM mode example for PHP 7.1+
<?php
//$key should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv, $tag);
    //store $cipher, $iv, and $tag for decryption later
    $original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
    echo $original_plaintext."\n";
}
?>

Prekvapi te, kdyz primo v dokumentaci pouzivaji stejny $iv?

 
Nahoru Odpovědět  +3 21. května 7:50
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 12 zpráv z 12.