Мой алгоритм шифрования

    Не так давно передо мною встала задача закодировать переписку пользователей. Целью задачи было пересылать уже закодированную строку от пользователя А пользователю Б. Строка кодируется и декодируется с помощью ключа, который известен обоим. Подразумевается, что сообщение от пользователя А отсылается на сервер пользователю Б, где пользователь Б его и забирает. Чтобы избежать получение данных в случае получения сообщения третьим лицом путем перехвата сообщения, либо доступа к серверу, где оно хранится, функцию было решено организовать на JavaScript, что дает возможность пользователям отсылать закодированную строку прямо из окна браузера.

    Бегло пробежавшись по некоторым способом шифрования, я решил написать собственный алгоритм. Суть алгоритма было решено свести к тому, чтобы перемешивать каждый отдельный символ в неким уникальным значением смешанным с ключом, причем так, чтобы значение, которое будет смешивать данные символы было уникальным и формировалось из заданного пароля или ключа. Творческой идеей для написания именно такого алгоритма послужил шифр Эль-Гамаля, метод преобразования Punycode и Base64. На нобелевскую премию я не претендую, но тем не менее решил поделиться собственным творением и…

    passCode — пароль, ключ. Так как пользователь задает данный параметр самостоятельно, а он может быть достаточно простым, то я кодирую ее дополнительно в MD5.
    Incode — кодируемая строка

    function txtencode(Incode, passCode)
    {
    	//Так как сам результат может содержать нежелательные символы, эта переменная содержит символы с помощью которых мы будем выдавать закодированный результат, который вдальнейшем сможем отправить без особых хлопот
    	var b52 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    	//Эти переменные будут меняться в процессе кодировки и создавать мешанину каждого кодируемого символа в отдельности
    	var maxPC = ifPC = 0;
    	//Уникализируем переменную maxPC. Ее значение будет происходить от суммы каждого юникодного значения символов пароля
    	for(var i=0; i<passCode.length; i++) maxPC += passCode.charCodeAt(i);
    	//Значение maxPCmod будет меняться на убывание, опять же в зависимости от юникодного значения символа пароля
    	//А вот значение maxPC сохраним, оно понадобиться вдальнейшем, чтобы присвоить переменной maxPCmod новое значение, когда то будет меньше 0.
    	maxPCmod = maxPC;
    	//Результат кодируемой строки. Изначально равно пустоте. 
    	var rexcode = "";
    	//Переменная содержит первый символ пароля: passCode.charCodeAt(numPC)
    	//С ее помощью будем перебирать пароль и перемешивать его с символом строки
    	var numPC = 0;
    	//Перебираем каждый символ строки
    	for(var i=0; i<Incode.length; i++) 
    	{
    		//Если все символы пароля перемешаны, начинаем перебор пароля с первого символа
    		if(numPC == passCode.length) numPC = 0;
    		//Присвоиваем переменной maxPCmod новое значение, если оно меньше нуля.
    		if(maxPCmod < 1) maxPCmod = maxPC+ifPC;
    		//Эта переменная нужна для создания уникального значения maxPCmod, и как следствие уникального символа, с которым будет перемешиваться символ исходной строки.
    		// Получаем ее путем деления по модулю значений maxPCmod и текущего используемого юникодного значения символа пароля 
    		//В целом постоянная мешанина переменных maxPCmod, maxPC и ifPC позволяет кодировать каждый отдельный символ исходной строки с уникальным значением, что подразумевает невозможность отследить какую-либо синхронизацию алгоритма
    		ifPC += maxPCmod % passCode.charCodeAt(numPC);
    		//Создаем непосредственно символ, с которым и будем перемешивать текущий символ строки
    		var iscode = maxPCmod % passCode.charCodeAt(numPC);
    		//Создаем мешанину, путем сложения предыдущей переменной с переменной текущего символа
    		var nCode = (Incode.charCodeAt(i)+iscode);
    		//Уменьшаем значение maxPCmod для ее дальнейшей уникализации
    		maxPCmod -= passCode.charCodeAt(numPC);
    		//Переходим к следующему символу пароля
    		numPC++;
    		//Это будет уникальный номер текущего символа.
    		//При делении закодированного символа на 52 число означает неполное частно, а буква остаток. 
    		//Например 22С означает 22*52+2, так как С второй по счету символ начиная с нуля.
    		rexcode += parseInt(nCode / 52) + b52.charAt(parseInt(nCode % 52));
    	}
    	//Возвращаем закодированную строку
    	return rexcode;
    }
    


    Функция декодировки практически аналогично предыдущей за небольшими исключениями

    function txtdecode(Incode, passCode)
    {
    	var b52 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    	var maxPC = 0;
    	for(var i=0; i<passCode.length; i++) maxPC += passCode.charCodeAt(i);
    	maxPCmod = maxPC;
    	ifPC = 0;
    	//Разбиваем строку на массив, который будет состоять из каждого закодированного символа
    	var Incode = Incode.match(/\d+\w/g);
    	var rexcode = "";
    	var numPC = 0;
    	for(var i=0; i<Incode.length; i++) 
    	{
    		if(numPC == passCode.length) numPC = 0;
    		if(maxPCmod < 1) maxPCmod = maxPC+ifPC;
    		ifPC += maxPCmod % passCode.charCodeAt(numPC);
    		var iscode = maxPCmod % passCode.charCodeAt(numPC);
    		//В отличии от фунции кодирования, тут дейтсвие происходит в обратную сторону
    		var nCode = (parseInt(Incode[i])*52)+parseInt(b52.indexOf(Incode[i].substr(-1)));
    		maxPCmod -= passCode.charCodeAt(numPC);
    		numPC++;
    		//И в результате соответственно уже не сложение, а вычитание
    		rexcode += String.fromCharCode(nCode-iscode);
    	}
    	//Уже можно вернуть return rexcode.
    	//Но для корректного отображения в браузере, я преобразую некоторые символы во мнемоники, а урлы преобразую в ссылки.
    	return rexcode.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/ /g, " ").replace(/\r\n|\r|\n/g,"<br />").replace(/(https?\:\/\/|www\.)([а-яА-Я\d\w#!:.?+=&%@!\-\/]+)/gi, function(url) 
    	{
    		return '<a target="_blank" href="'+ (( url.match('^https?:\/\/') )?url:'http://' + url) +'">'+ url +'</a>';
    	}); 
    }
    


    Результат можно увидеть на сайтах avtodot.ru, baby-all-pro.ru и building-repairs.ru

    Юридические аспекты шифрования данных

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 29

      +4
      А чем вас не устроили существующие крипто-решения для JavaScript?
        –7
        Просто было интересно создать свое.
          +8
          Создать свое без опыта 10 лет работы в области — можно не пытаться. Точнее, пытаться то можно, но использовать в реальных системах мягко говоря не рекомендуется.

          Вот было бы интересно сравнить хотя бы с той же энигмой. Ведь последняя сейчас считается крайне слабой криптосистемой, а выглядит более сложной, чем ваш метод шифрования, который, по сути, шифр Цезаря с небольшой доработкой.
            +3
            Вероятно вы имели ввиду шифр Виженера? В Цезаре нет кодового слова.
              +7
              Да, точно. Я вообще очень слаб в криптографии, какие-то основы знаю, но сам предпочитаю не касаться этой темы и 12-ти метровой палкой, что обычно и советую всем, если только у них нет цели освоить криптографию. Особенно не касаюсь, если это продуктовые решения. Настроить https на nginx через сертификат — и то обычно предпочитаю, чтобы кто-то более компетентный проверил.
              Но даже моих познаний достаточно, чтобы понять, что в статье очень слабый метод.

              Вот если бы автор не рекомендовал эту поделку, а сделал как небольшой пример, в стиле «урок», потом дописал бы «так делать ни в коем случае нельзя», да и реализовал один из более стойких алгоритмов симметричного шифрования — думаю, у него бы не получился такой хабра-суицидальный пост, а пополнение в коллекции уроков. Жаль, что mmotor предпочел иной путь.
        +20
        просто оставлю это здесь
        habrahabr.ru/post/181372
          +2
          Кроме того, шифрование джаваскриптом в браузере это проблема курицы и яйца.
          +6
          Не так давно передо мною встала задача закодировать переписку пользователей.

          Кодирование != шифрование
            +2
            Кодирую переписку пользователей от алкоголя и курения. Дорого. В лс.
            +1
            Очередное изобретение велосипеда.

            code.google.com/p/crypto-js
              +1
              Кстати, n-ый символ (где n — длина passCode) у вас не зашифрован. Так как в конце первого прохода по паролю maxPCmod равен коду последнего символа пароля, и по его же модулю это ноль.
                0
                А каким каналом между пользователями передается симметричный ключ?
                  +7
                  RLY?

                  var top_secret_info = txtencode('hello', 'qqqqq');
                  print(txtdecode(top_secret_info, 'xxxxx')); // hello
                  

                  ideone.com/59CyJK
                    +2
                    Ну, во-первых — это красиво.
                      0
                      deleted
                        +1
                        Ну так у автора все-таки md5 берется от пароля=)
                        +1
                        Казалось бы, не май месяц, а весене-осенние посты постоянно пребывают
                          +11
                          Вы показали хороший пример как делать не нужно.
                            +2
                            Эль-Гамаль то тут при чем?

                            Не так давно передо мною встала задача закодировать переписку пользователей.


                            Может base64 было бы достаточно? Или недостаточно «мешанины»?
                              +2
                              Первое правило криптографии: не изобретайте свой шифр.
                              Лучше пройдите курс на Coursera, там есть хороший по криптографии, потом посмеетесь над своей поделкой)
                              Количество минусов как бы намекает на то, что подобные решения никаким образом не должны попадать в рабочие продукты, и вообще статью лучше спрятать, чтобы никто случайно не воспользовался.
                              0
                              IMHO, ваш алгоритм недалеко ушёл от ROT13.
                                –17
                                Я полагаю, что любые попытки написать свой алгоритм шифрования достойны похвалы. Даже если Ваш алгоритм и не является крипто стойким, само наличие разных алгоритмов даёт пользователям возможность выбора, а злоумышленникам усложняет жизнь. Что касается высказываний большинства комментаторов, то, возможно, они «типа шибко умные», но никто особо не заморачивается тем, чтобы указать на ошибки. А может они просто не могут это сделать? Может, ума не хватает?
                                  +5
                                  Вы, видимо, решили не читать комментарии вовсе, иначе бы заметили, что создание «своего криптоалгоритма» без опыта — это одна большая ошибка, а в конкретном опусе вообще нет ничего правильного — одна сплошная дыра, видимость защиты. Так как вы не читали комментарии, позволю себе повторить лично для вас ссылку: habrahabr.ru/post/181372

                                  На счёт «наличие разных алгоритмов даёт возможность выбора» — алгоритмов с математически доказанными свойствами стойкости масса, среди них на специальных конкурсах, где проверяют математическую базу и все доказательства годами (!), например, AES и SHA, выбираются лучшие из лучших. Поверьте, не нужны человечествую такие «альтернативы», которую автор предложил. Изобретение криптографических примитивов — это не развлечение на выходные.
                                    +2
                                    Как-то у меня была идея, как раз как развлечение на выходные: сделать шифрование на основе фильтра Калмана вдруг неожиданно. Точнее само шифрование на основе системы диф. уравнений, где кодовое слово определяло бы её вид, а входные данные — были бы возмущениями этих дифуров, затем подмешивался бы случайный шум, а дешифрация осуществлялась бы фильтром. Но немного подумав пришел к нескольким выводам: превратить это из идеи в работающий алгоритм займет уже несколько месяцев, вот почти наверное что-то подобное уже есть, а так же — скорее всего, есть глупый и смешной способ взлома, благодаря чему окажется, что время потрачено впустую. Хотя идея звучит круто: один и тот же поток каждый раз будет давать разный результат, причем случайный, шифрация поточная, можно подмешивать так же несколько случайных входов — есть место для фантазии. Правда объем данных увеличится сильно, ну да ладно.
                                    Раз я уже тут сказал эту идейку — вот просто ради интереса — есть ли что-то подобное и какой самый очевидный недостаток этого метода?

                                    Но мораль такая, что прежде чем алгоритм пополнит возможность выбора, пройдет много времени исследований, закрытия дырок, доказательства стойкости, а потом к вам постучится МВД и потребуют лицензирования (если захотите заработать денежек на своих наработках).
                                      0
                                      ФСБ скорее только, а не МВД. Лицензированием по криптографии они у нас в стране занимаются.
                                        0
                                        Нечто похожее, но на системах линейных уравнений, уже есть — Learning With Errors. Насколько я помню, LWE считается (но не доказано) сложной проблемой для квантовых компьютеров, поэтому активно продвигается в post-quantum криптосистемах.

                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                  Самое читаемое