Сразу скажу, что на создание очередной самописной хеш-функции вдохновили поседение темы на хабре:
Почему я не лезу в криптографию, Вы опасно некомпетентны в криптографии и ветка обсуждения в теме про алгоритм хеширования «Стрибог», который 1 января 2013 стал новым стандартом хеширования в РФ.
Почему я не лезу в криптографию, Вы опасно некомпетентны в криптографии и ветка обсуждения в теме про алгоритм хеширования «Стрибог», который 1 января 2013 стал новым стандартом хеширования в РФ.
Зачем?
- Чем больше одинаковых функций защиты используется в системах, тем больше вероятность того, что есть тот, кто нашел в них лазейку, но молчит и пользуется ей, по крайне мере желающих купить такие лазейки за приличные деньги всегда будет много, а если есть спрос, то будут искаться и варианты что-то предложить.
- «Я опасно некомпетентен в криптографии» и чтобы что-то исправить в этом плане я экспериментирую.
Ни о каком продакшн-варианте речь, конечно, не идет.
Алгоритм, который родился за 5 минут и был реализован за 60 с перерывом на чай
Я решил стремиться к технологической сингулярности и использовал алгоритмы, которые до меня некоторое время продержались с пометкой «надежный», а именно SHA1, MD5
Сам алгоритм
- Формируется 16 разных форм исходного текста: кодирование в UTF-8, hex-кодирование, реверс, base64 и разные композиции этих форм
- От этих форм высчитываются значения функций MD5 и SHA1, значения SHA1 обрезаются до 128 бит
- Получается таблица 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/
Добавить комментарий