Не так давно передо мною встала задача закодировать переписку пользователей. Целью задачи было пересылать уже закодированную строку от пользователя А пользователю Б. Строка кодируется и декодируется с помощью ключа, который известен обоим. Подразумевается, что сообщение от пользователя А отсылается на сервер пользователю Б, где пользователь Б его и забирает. Чтобы избежать получение данных в случае получения сообщения третьим лицом путем перехвата сообщения, либо доступа к серверу, где оно хранится, функцию было решено организовать на JavaScript, что дает возможность пользователям отсылать закодированную строку прямо из окна браузера.
Бегло пробежавшись по некоторым способом шифрования, я решил написать собственный алгоритм. Суть алгоритма было решено свести к тому, чтобы перемешивать каждый отдельный символ в неким уникальным значением смешанным с ключом, причем так, чтобы значение, которое будет смешивать данные символы было уникальным и формировалось из заданного пароля или ключа. Творческой идеей для написания именно такого алгоритма послужил шифр Эль-Гамаля, метод преобразования Punycode и Base64. На нобелевскую премию я не претендую, но тем не менее решил поделиться собственным творением и…
passCode — пароль, ключ. Так как пользователь задает данный параметр самостоятельно, а он может быть достаточно простым, то я кодирую ее дополнительно в MD5.
Incode — кодируемая строка
Функция декодировки практически аналогично предыдущей за небольшими исключениями
Результат можно увидеть на сайтах avtodot.ru, baby-all-pro.ru и building-repairs.ru
Юридические аспекты шифрования данных
Бегло пробежавшись по некоторым способом шифрования, я решил написать собственный алгоритм. Суть алгоритма было решено свести к тому, чтобы перемешивать каждый отдельный символ в неким уникальным значением смешанным с ключом, причем так, чтобы значение, которое будет смешивать данные символы было уникальным и формировалось из заданного пароля или ключа. Творческой идеей для написания именно такого алгоритма послужил шифр Эль-Гамаля, метод преобразования 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
Юридические аспекты шифрования данных