
Данная статья являет собой небольшую историю о том, как мне понадобилась простая криптография.
Вот, думаю, у каждого программиста настает такой момент, когда нужно в своей программе быстро и просто зашифровать строку.
Qt имеет несколько классов, предназначенных для шифрования. Когда нужно просто хранить пароль, можно хранить его хэш и сравнивать с хэшом введенного пароля, но что делать, если нужно хранить тексты, или другие строки в зашифрованном виде, а в программе их показывать уже расшифрованными.
Кому интересно, прошу под кат.
Здесь будет описание пути того, как я дошел к этому методу, кому нужны только исходники: в конце статьи ссылка на гитхаб.
Итак, для начала я думал как можно проще всего зашифровать строку другой строкой. Мне попадались всякие типы шифрования вроде rsa, sha и тому подобное, но для новичка это сложно, а в qt для работы с ними — вообще нужно городить костыли с помощью QSsl и тому подобного, это тоже не вариант для такой простой схемы, как на заголовочном изображении. Нам ведь нужны все два метода — зашифровать и расшифровать. И вот, я вспомнил про чудесный XOR. Это признали одним из самых стойких шифрований, но здесь я столкнулся с очередной задачей: для его работы ключ и строка для шифрования должны быть одной длины. И здесь получаем то, что можно просто взять произвольной длины ключ и брать XOR посимвольный. При подходе к концу ключа — крутить его заново. Ну и было решено сделать класс статическим(не люблю я париться с объектами, да и не нужны они для данной задачи).В классе описываем два метода: cryptString(QString toCrypt) и decryptString(QString toDecrypt). Разберу только работу шифровальщика, расшифровщик работает точно так-же.
Перво-на-перво, я решил объявить наш ключ:
static const QString kEncryptorString = QString("any string for key");
Ну и сам метод шифровки:
static QString cryptString(QString toCrypt)
{
QString resultString = "";
for ( int i = 0; i < toCrypt.length(); i++)
{
resultString.append(QString(QChar(toCrypt[i]).unicode()^QChar(kEncryptorString[keyIndex(i)]).unicode()));
}
return resultString;
}
Здесь мы берем и просто идем по каждому символу исходной строки и применяем к нему XOR соответствующего символа нашего ключа. Соль в том, что-бы не выйти за пределы длины ключа. Для этого написал простой метод, который возвращает нормированный индекс, то есть, если у нас длина шифруемой строки -20 символов, а длина ключа — 9, то при подходе к 10-му символу строки мы должны взять первый символ ключа. Вот это и делает метод keyIndex(i).
static int keyIndex(int index)
{
int len = kEncryptorString.length();
int multiple = index / len;
if ( index >= len ) {
return index - (len * multiple);
}
return index;
}
Так же пришлось все это преобразовывать из типа в тип, что-бы предать QString'овому методу append, но это уже рутина.
В итоге, я получил один заголовочный файл, который просто подключить и просто использовать.
Как и обещал, исходник: GitHub