Криптография — это просто. Создаем хеш-функцию. x13Hash

от автора

Сразу скажу, что на создание очередной самописной хеш-функции вдохновили поседение темы на хабре:
Почему я не лезу в криптографию, Вы опасно некомпетентны в криптографии и ветка обсуждения в теме про алгоритм хеширования «Стрибог», который 1 января 2013 стал новым стандартом хеширования в РФ.

Зачем?

  • Чем больше одинаковых функций защиты используется в системах, тем больше вероятность того, что есть тот, кто нашел в них лазейку, но молчит и пользуется ей, по крайне мере желающих купить такие лазейки за приличные деньги всегда будет много, а если есть спрос, то будут искаться и варианты что-то предложить.
  • «Я опасно некомпетентен в криптографии» и чтобы что-то исправить в этом плане я экспериментирую.

Ни о каком продакшн-варианте речь, конечно, не идет.

Алгоритм, который родился за 5 минут и был реализован за 60 с перерывом на чай

Я решил стремиться к технологической сингулярности и использовал алгоритмы, которые до меня некоторое время продержались с пометкой «надежный», а именно SHA1, MD5

Сам алгоритм

  1. Формируется 16 разных форм исходного текста: кодирование в UTF-8, hex-кодирование, реверс, base64 и разные композиции этих форм
  2. От этих форм высчитываются значения функций MD5 и SHA1, значения SHA1 обрезаются до 128 бит
  3. Получается таблица 32×32 состоящая из значений с длиной в 4 бита (1 hex-сивол), используя xor, мы её сжимаем по диагонали в одну 128 битную строку — это и будет нашим результатом

реализация x13Hash

window.x13hash = (function (Sha1, md5, encode64) 	{ 		var strReverse = function (str) 		{ 			return str.split("").reverse().join(""); 		}  		var toHex = function (str) 		{ 			var hex = '';  			for(var i=0; i < str.length; i++) 				hex += '' + str.charCodeAt(i).toString(16);  			return hex; 		}  		var x13hash = function () 		{ 			 		};  		x13hash.prototype.getSomeFormsFromData = function (data) 		{ 			var d = [];  			d[0] = data;  			d[1] = Utf8.encode(data); 			d[2] = toHex(data); 			d[3] = encode64(data); 			d[4] = strReverse(data);  			d[5] = encode64(d[1]); 			d[6] = strReverse(d[2]); 			d[7] = strReverse(d[3]); 			d[8] = strReverse(d[1]);  			d[9] = encode64(d[5]); 			d[10] = strReverse(d[9]); 			d[11] = toHex(d[1]); 			d[12] = strReverse(d[11]); 			d[13] = toHex(d[4]); 			d[14] = encode64(d[8]); 			d[15] = strReverse(d[14]);  			return d; 		}  		x13hash.prototype.getHashTableFromDataForms = function (dataForms) 		{ 			var hashTable = [];  			for (var k in dataForms) hashTable.push(md5(dataForms[k])); 			for (var k in dataForms) hashTable.push(Sha1.hash(dataForms[k]).substr(0, 32));  			return hashTable; 		}  		x13hash.prototype.zipHashTable = function (hashTable) 		{ 			var res = [], k = 0, xorVal, xorInd = 0;  			for (var i = 0; i < 31; i++) 			{ 				res[i] = Number('0x' + hashTable[0][i]);  				for (var j = 1; j < 32; j++) 				{ 					xorInd++; 					xorVal = Number('0x' + hashTable[j][xorInd % 32]); 					res[i] ^= xorVal; 				}  				res[i] = res[i].toString(16, 1); 			} 			return res.join(''); 		}  		x13hash.prototype.hash = function (data) 		{ 			var d = this.getSomeFormsFromData(data); 			var hashTable = this.getHashTableFromDataForms(d);  			return this.zipHashTable(hashTable); 		}  		return new x13hash();   	} )(Sha1, md5, encode64); 

Или можно скачать рабочий пример и поиграться вживую.

Вместо заключения

Можно было еще сделать таблицу замен, которая бы формировалась похожим образом, сделать порядок расчета зависящим от хеш-функции, сделать более сложным алгоритм сжатия — на что фантазии хватит, но это всего лишь эксперимент.

ссылка на оригинал статьи http://habrahabr.ru/post/188322/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *