Криптиране

dakata__92

Super Moderator
Как си криптирате паролите? Преди се ползваше md5 и в доста сайтове съм го ползвал, но напоследък забелязвам, че хората използват:
http://php.net/manual/bg/book.mcrypt.php
Бихте ли ми дали функции за криптиране и декриптиране на стринг, които са най-актуални с времето. Смисъл в момента, какъв е начина за криптиране на пароли, като използването на някакъв ключ е ясно.
 
След доста четене, драснах ето този код. Какво мислите за него? Давайте мнения :)

PHP:
class Crypt
{
	public function __construct()
	{
		
	}
	
	public function encrypt($string, $key)
	{
       $string = trim($string);
       $key = trim($key);
	   
	   $iv = mcrypt_create_iv(
			mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
			MCRYPT_DEV_URANDOM
		);

		return $encrypted = str_rot13(
			base64_encode(
				$iv .
				mcrypt_encrypt(
					MCRYPT_RIJNDAEL_128,
					hash('sha256', $key, true),
					$string,
					MCRYPT_MODE_CBC,
					$iv
				)
			)
		); 
	}
	
	public function decrypt($string, $key)
	{
		$string = base64_decode(
			str_rot13( 
				trim($string)
			)
		);
		$key = trim($key);
		
		$iv = substr($string, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

		return $decrypted = rtrim(
			mcrypt_decrypt(
				MCRYPT_RIJNDAEL_128,
				hash('sha256', $key, true),
				substr($string, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
				MCRYPT_MODE_CBC,
				$iv
			),
			"\0"
		);
	}
}
 
Не мога да разбера защо накрая все си пишете някакви си ваши тествани, нетествани кодчета... Какво по-просто от функция в php?

Ето ти и polyfill https://github.com/ircmaxell/password_compat

Направо го мини 2 пъти през rot13, няма по-сигурно от това...
 
lam3r4370 каза:
Не мога да разбера защо накрая все си пишете някакви си ваши тествани, нетествани кодчета... Какво по-просто от функция в php?

Ето ти и polyfill https://github.com/ircmaxell/password_compat

Направо го мини 2 пъти през rot13, няма по-сигурно от това...

Видя ли кода колега? Нали се ползва същият принцип като на тази функция просто е под моят контрол. rot13 e просто за разбъркване на криптираният низ. Ако не бях дал кода, даже нямаше да разбереш как да го декодираш. Идеята ми не е само да криптирам пароли, а и други стрингове, като така имам криптер и декриптер, и бих могъл даже и шифрирани съобщения да пращам.
 
novakabg каза:
Запоявадай нещо лесно без много сложност :) аз го ползвах преди няколко дена.

http://www.php.net/crypt
На мен ми е нужно да имам и декриптираща функция, затова си и написах собствен клас по темата. :)
 
Криптирането на пароли е НАЙ-ГОЛЯМАТА глупост която можеш да направиш с тях. ВИНАГИ ГИ ХЕШИРАЙ!!!!

Ако толкова ти трябва криптиране:
PHP:
$method = 'aes-256-cbc';
$secret = 'SOME SECRET STRING ONLY YOU KNOW ABOUT aka password'; // base64_encode(random_bytes(128));

$string = 'Test string';

// Encrypting
$iv = random_bytes(16);
$encrypted = base64_encode($iv).openssl_encrypt($string, $method, $secret, false, $iv);


// Decrypting
if (strlen($encrypted) < 24)
{
	throw new \InvalidArgumentException('Invalid encrypted value');
}
$iv = base64_decode(substr($encrypted, 0, 24));
$decrypted = openssl_decrypt(substr($encrypted, 24), $method, $secret, false, $iv);

echo $decrypted; // Test string


Хората учат математика по 15 години за да се занимават с криптиране. Не си мисли, че само защото някой не ти знае кода, не може да го разбие.
 
И забравих да спомена, че mcrypt не е сигурно вече, ползвай, както колегата горе е дал примера, openssl
 
Приятели, не че нещо но какво е криптиране и какво значи хеширане? Имате md5() примерно. Това е едностранна хешираща функция без обратно получаване на началният стринг. Тоест хеширането е едностранно криптиране на даден низ. Това, че не е дадена функция за обратно връщане на низа, изобщо не значи, че неможе да бъде декриптирана. Това е алгоритъм, който 123456 винаги ще ти го дава по един и същи хеширан вид. Тоест това, че не е дадена функция за дехеширане, не значи, че неможе. Да вземем примера с моят код. Ако премахна метода decrypt идете учете 15 години и отделете седмици наред за да разкодирате някаква парола. Тоест няма как да разбие паролите, ако незнае алгоритама ми за криптиране. Тоест да едностранното хеширане (криптиране) е по-сигурно, защото декриптиращ алгоритъм не е достъпен на сайта примерно, но както казах аз пък мога да искам да направя криптиран чат по някакъв ключ, тоест приложения на такъв клас много, не само за парола. Та хеширането си е чисто криптиране, разлики няма и всичко се изучава в науката Криптография, занимаваща се със семантиката, а математиката, тя е алгоритъма за изпълнение. Достатъчно съм чел по темата, за да правя разликите и сам. Просто исках да си създам собствен криптер клас, а дали ще го ползвам в приложенията си за пароли темата е друга. Например, винаги мога да направя:
PHP:
md5(sha1(md5("стринг")));
И нека се пробва някой да разбие алгоритъма. Просто ми стана интересно, какво е актуално в момента. Например от горният коментар разбирам, че
mcrypt не е сигура (защото?), като сега ще се поинтересувам повече от openssl тъй като е по-сигурна била (с какво?). Ето това искам, а именно да науча нещо интересно, а не тривиалните неща свързани с елементарни неща. Благодаря предварително за отговорите на всички, темата продължава да ми е интересна. :?:
 
Ами google it. И както колегата каза това, че не се знае по какъв начин си я криптирал далеч не значи, че не може да се декриптира.
 
dakata__92 каза:
Това, че не е дадена функция за обратно връщане на низа, изобщо не значи, че неможе да бъде декриптирана.
Когато подадеш един и същи текст два пъти на една хеш функция, можеш да очакваш един и същи резултат и в двата случая. Когато подадеш 2 различни текста, не можеш винаги да очакваш 2 различни изхода (колизии). Алгорътъмът md5 не е популярен вече, защото са намерили лесен начин да правят колизии (https://en.wikipedia.org/wiki/MD5#Security).
Не можеш просто да "декриптираш"/"дехешираш" един хеш. Мога да ти дам един прост пример:
Код:
function encrypt($number) {
return pow($number, 2) * 10 + 7;
}
Сега си представи, че имаш резултат 47 от извикването на функцията encrypt(). Тогава числото, което си подал на функцията encrypt() може да е 2 или -2 т.е. функцията decrypt() трябваше да връща 2 неща. Идеята на криптирането е да имаш един резултат при криптиране и декриптиране. Сега си представи, че това може да са 2 напълно различни текста със напълно различна дължина и те могат да имат един и същи хеш. Това е причината да няма "дехешираща" функция, а не защото ще е по-сигурно ако няма такава функция. Ако беше възможно да се направи, тогава до сега някой ще го е направил. Целта на криптографските хешове е да има възможно най-малко колизии.
dakata__92 каза:
Ако премахна метода decrypt идете учете 15 години и отделете седмици наред за да разкодирате някаква парола. Тоест няма как да разбие паролите, ако незнае алгоритама ми за криптиране.
Това, че слагаш sha256, base64, rot13 и други, не ти прави кода по-защитен, дори и да не ни беше дал декриптиращата функция. Явно не си чувал за Security through obscurity и Cryptanalysis. Също прочети и за Slide attack. Последно, да не забравяме за Kerckhoffs's principle, който гласи, че една криптосистема трябва да е защитена, дори когато знаем всичко за нея освен ключа.
dakata__92 каза:
mcrypt не е сигура (защото?), като сега ще се поинтересувам повече от openssl тъй като е по-сигурна била (с какво?).
Можеш да прочетеш първия коментар и в него пише защо.
 
Като допълнение само ще вметна, че bcrypt е хешираща функция, но с вграден salt и затова при два еднакви текста ти дава 2 различни хеша, също така хубаво е преди bcrypt да ги минеш през sha1
 
Не е хубаво да минаваш паролите през каквото и да е (sha1, md5) преди bcrypt. Ако използваш sha1 преди bcrypt си задълбочаваш проблема с колизиите.

Bcrypt може да използва и salt, който ти му задаваш.

Пример за brypt:
$2y$15$Fj/4LRssD9OL77zW69m2EuoLqMj84nr2iwm18B7c5.KAS8yKvyjMi #base64 (64^54 възможности)

Пример за sha1:
c228067d868784a3bc64310c2ce110d7bbd2e11e # hex (16^40 възможности)

64^54 >16^40
 
Имах предвид sha512 и ето защо е хубаво да се прави

https://blogs.dropbox.com/tech/2016/09/how-dropbox-securely-stores-your-passwords/

Some implementations of bcrypt truncate the input to 72 bytes, which reduces the entropy of the passwords. Other implementations don’t truncate the input and are therefore vulnerable to DoS attacks because they allow the input of arbitrarily long passwords. By applying SHA, we can quickly convert really long passwords into a fixed length 512 bit value, solving both problems.
 
Това има смисъл само ако искаш да ползваш пароли над 72 символа.
sha512 не се събира в 72 символа ако е в base64 (стават 88 ), а ако bin, може има празни битове (0х00), което за bcrypt е като да имаш празна парола. Това означава, че или трябва да отрежеш 16 символа или да използваш sha256 или sha384.
 

Горе