Разлики при криптиране, хеширане и посоляване

Въведение

Всеки човек, използващ интернет, се е сблъсквал с процесите по криптиране и хеширане на информация, но може би единствено изучените програмисти знаят какви процеси стоят зад тези сложни термини.

Криптирането е основен процес при сигурния трансфер на данни, използван в комуникацията между повечето модерни устройства. Предаваната информация се криптира така, че единствено желаният получател да може да разтълкува съдържанието й. Така зловредни опити за разчитане на информацията при процеса на трансфер са напрактика безполезни. Пример за това би било при плащане с банкова карта, външно лице да се опита да извлече банковата ни информация, като проследява криптираните данни от транзакцията.

При хеширането основният проблем, който се разрешава, е проверката за интегритет на данни. Стойността получена при хеширането на дадени данни е уникална, като всяка малка промяна в данните води до напълно различна хеш стойност. Освен това хеширането не е обратим процес за разлика от криптирането т.е. при наличие на хеш стойността не можем да възстановим първоначалния вид на данните. Така например безопасно могат да се съхраняват пароли чрез тяхната уникална хеш стойност без притеснения, че хакер, получил достъп до базата, ще получи достъп и до акаунтите на потребителите

Но какво ще стане, ако хакерът в горния пример забележи, че в базата с хешираните пароли има еднакви стойности? Това би подсказало на хакера, че съответните потребители използват често срещани пароли. Всеки уважаващ себе си хакер би успял да разбие тези лесни пароли за отрицателно време. За да се предотврати този проблем, повечето модерни приложения използват техниката посоляване. Посоляването е процесът по прибавяне на допълнителна последователност от символи към потребителската парола преди процеса на хеширане. Постига се усложняване на потребителската парола. Така двама потребители с еднаква парола, ще имат различни хеш стойности в базата данни, което значително усложнява работата на злонамерените хакери.

Нека разгледаме по-подробно гореописаните понятия.

Криптиране

Криптирането не е процес, който навлиза в употреба с появата на компютрите. Исторически данни показват, че още древните египтяни са използвали система за промяна текстове си, така че само избрани лица от аристокрацията да разберат значението им.[1]

Шифърът на Цезар

Един от най-известните ранни шифри е този използван от римския император Юлий Цезар. Цезар е използвал примитивна версия на "Shift" шифър, за да води скрита от враговете си кореспонденция. Шифърът на Цезар взема дадено съобщение и заменя всяка самостоятелна буква в него с буквата на 3 позиции напред в азбуката.

Например в криптирано съобщение думата ВОЙНА ще бъде заменена с ЕСМРГ, тъй като на буквата В отговаря буквата Е, на ОС и т.н. Когато получателят види криптираното съобщение той трябва да използва обратния процес декриптиране, за да разбере съдържанието му. Това изисква предварителна "уговорка" между двете лица, тоест криптиращия участник трябва да сподели метода на декриптиране на своя събеседник преди започване на криптираната комуникация.

В нашия пример съобщението ЕСМРГ ще бъде декодирано, като за всяка негова буква бъде заменена с тази на 3 позиция преди нея в азбуката. Това е обратният процес на операцията по кодиране. С по-математически термини, ако представим буквите от азбуката чрез числата от 0 до 29 (A е 0, Б е 1, ..., Я е 29), то функцията на кодиране е Fn(x) = (x + n) mod 30, където n е броят измествания надясно (при Цезаровия шифър n = 3). Функцията за Декориране Gn(x) = (x – n) mod 30.[2]

Цезаров шифър в действие

Стойност на преместването: 0

Разбиване на криптиращ алгоритъм

Ефективността на един шифър или алгоритъм за криптиране се определя чрез времето нужно за разгадаването му – разбиването на ключа. Алгоритъмът на Цезар, колкото и примитивен да изглежда, е бил разгадан едва след 9 века от арабски учен.[2] Въпреки това, ако е известен методът – изместване на азбуката с дадено число, то са нужни 30 на брой опита, за да се разгадае ключа, равен на 3.

Съществуват различни вариации на шифъра на Цезар, които се опитват да увеличат сложността на алгоритъма. Ако се използва индивидуално подреждане, такова че всяка буква отговаря на произволна друга възможните комбинации за ключ стават 30!. Това е число с 32 нули, което би довело читателя до мисълта, че този шифър би бил неразбиваем. Това ще е вярно, ако се използва наивен brute force метод за решаването на проблема.[6]

При анализирането на даден криптиращ алгоритъм повече на брой ключове, не винаги значи по-сигурен алгоритъм. Съществуват техники като семантичния анализ, които лесно разбиват семейството от шифри, произлизащи от Цезаровия. Семантичният анализ проверява колко често се среща всяка буква в шифрованото съобщение. Това носи изключително много информация за възможните ключове, тъй като най-срещаните букви в езика, ще отговарят на най-срещаните букви в криптираното съобщение.[3]

Например петте най-често срещаните букви в българския език са А, И, О, Е и Н.[4] Нека си представим как сме шпиони, които са се добрали до кодираното съобщение ЧА КУЕ ЖЧРЮДЗ ЖЧ ИЮЛЖЧЬЮКЮЛ ОБДЦЬЖЧ ЧЙЕБЦ Б ИУЛМЩЧЕ ГУЕ ЩЧК и искаме да го разгадаем. Ако анализираме броя срещания на всяка буква ще забележим, че най-често срещана в съобщението е буквата Ч, следвана от Е, Ж, Ю. Много по-вероятно е кодираната буква Ч да отговаря на А в реалното съобщение, отколкото на буквата Щ например.

Съобщението е: АЗ СЪМ НАЧЕЛО НА ПЕТНАДЕСЕТ ХИЛЯДНА АРМИЯ И ПЪТУВАМ КЪМ ВАС

Анализатор на честотата на символите

Символ Честота

Криптиращи ключове

Друг примерен вариант е шифърът на Виженер. Нека си представим ключа на обикновения шифър на Цезар, като една буква – примерно ключ Г. Това ще означава, че местим всяка буква от оригиналното съобщение с 3 позиции напред, тъй като буквата Г е третата буква в азбуката, ако започнем броенето от 0. Горният вариант на шифър, където всяка буква сочи към друга буква, има ключ с дължина 30 – на всяка буква от азбуката показваме с колко да се измести чрез друга буква от азбуката. Тогава шифърът на Виженер може да има ключ с произволна дължина.[3]

Например ключа ГБК означава, че първата буква в нашето съобщение ще бъде преместена с 3 позиции напред, тъй като Г е третата буква от азбуката, като започнем от 0. Следващата буква в нашето съобщение ще бъде криптирана чрез изместването й на 1 позиция напред в азбуката (Б = 1). Третата буква в нашето съобщение ще бъде изместена с 10 позиции напред (К = 10). След това повтаряме процеса по криптиране, като започваме от четвъртата буква на съобщението и първия символ на ключа.

Нека криптираме съобщението ЗАПОЧВАМЕ ВОЙНА с ключа ГБК. Това се получава, като заместим З с буквата 3 позиции напред – К, поради ключа Г, после А с Б заради Б, П с Щ заради К, О със С заради Г и т.н. Крайният резултат от криптиращия алгоритъм е низът КБЩСШМГНП ЕПУРБ.

Шифърът на Виженер на пръв поглед се справя с проблема с често повтарящите се букви. В зависимост от дължината на ключа един път буквата А може да се превърне в Б, друг път в С. Така семантичният анализ изглежда няма да помогне при анализиране на криптиращия алгоритъм. Това обаче не е напълно вярно. Съществуват множество алгоритми, чрез които може да се определи дължината на ключа. Когато веднъж знаем дължината на ключа, разбиването на шифъра на Виженер се свежда до това да разбием няколко на брой последователни Цезарови шифъра. Като дори тогава можем да използваме семантично изследване във всеки един отделен шифър.[3]

Криптиране с ключ

128/256-битови ключове

Модерните ключове представляват поредица от нули и единици обикновено с дължина 128 или 256 символа. Известни са още като 128-битови или 256-битови ключове. Възможните ключове с дължина 128 бита са 2 на степен 128 или число с 38 нули. Това е така, защото на всеки бит избираме дали да е 0 или 1. Имаме 128 избора или 2*2*2...*2 = 2128 възможни комбинации. Ако отгатвате по 1 милиард възможни ключа в секунда и сте започнали при самото създаването на Вселената, няма все още да сте минали 1 процент от всички възможни комбинации.

Цялата информация, която се предава в интернет пространството може да се представи като поредица от нули и единици. За простота ще използваме ASCII таблицата. Тя показва как можем да представим текст чрез поредица от числа, като заменим всеки символ с дадено число. Например малката латинска буква a се представя чрез числото 97, малкото b с 98, малкото z с 122, голямото A със 65, B с 66, Z с 90. Всъщност се извършва вид кодиране – всеки символ се кодира със зададено в таблицата число. Имаме кодиране на компютърната азбука, състояща се от 256 символа в числата от 0 до 255. Така думата ball ще бъде преведена до числата 98, 97, 108, 108. Какво общо имат тези числа с битовете?

Кодиране с 4-битов ключ

За да отговорим на този въпрос, трябва да разбираме как се преминава от десетична бройна система в двоична бройна система. Записът на числото 108 в десетична бройна система показва, че имаме 1 стотица, 0 десетици и 8 единици. Можем да запишем числото 108 като 100 * 1 + 10 * 0 + 1 * 8. Ако заменим със степени на десетката, получаваме (102) * 1 + (101) * 0 + (100) * 8. Така числото 101 в двоична бройна система означава, че имаме (22) * 1 + (21) * 0 + (20) * 1 = 4 * 1 + 2 * 0 + 1 * 1 = 5. Така всеки бит показва дали ще включим съответна степен на двойката при получаване на финалното число или не. Числото 101 показва – включваме 4, не включваме 2, включваме 1, получаваме 5 след сумиране. Същото е и при числото 108 в десетична бройна система – нулата показва, че нямаме десетици, но имаме 1 стотица и 8 единици. Числото 108 в двоична бройна система е 01101100 или (27) * 0 + (26) * 1 + (25) * 1 + (24) * 0 + (23) * 1 + (22) * 1 + (21) * 0 + (20) * 0 = 128 * 0 + 64 * 1 + 32 * 1 + 16 * 0 + 8 * 1 + 4 * 1 + 2* 0 + 1 * 0 = 108.

Вече знаем, че думата ball се кодира до последователните числа 98, 97, 108, 108, които в двоична бройна система се изписват така: 01100010, 01100001, 01101100, 01101100. Първата нула е използвана за уеднаквяване на дължината на символите – така знаем, че първите 8 бита са 1 символ, следващите 8 бита са втория символ и т.н. Сега спокойно можем да представим низа ball като последователността от 32 бита 01100010011000010110110001101100. Ще използваме 4-битовия ключ 1100 за кодиране на горната последователност. Самият ключ не ни е достатъчен да кодираме съобщението – трябва ни функция на кодирането.

Ще използваме операцията побитово или, изписвана още "|". Функцията приема два бита и връща резултат 0, ако и двата бита с 0 или 1 във всички останали случаи. Започваме да криптираме всички групички от 4 бита в първоначалното съобщение като използваме ключа и дефинираната функция. От първата група 0110 | 1100 получаваме 1110 с финален резултат 11101110111011011110110011101100. След това можем да превърнем криптираната поредица от битове в четири числа в десетична бройна система, които пък да превърнем в последователност от символи чрез ASCII таблицата.

Така криптирано съобщение с 4-битовия ни ключ изглежда по този начин: îíìì

Криптиране с битов ключ

Симетрично криптиране

Симетричното криптиране използва един ключ за криптиране и декриптиране на данните. Процесът по криптиране на данните със споделен ключ не изисква големи количества изчислителна мощ. Освен това създаването на такива ключове е сравнително бърза операция. Основният проблем свързан със симетричното криптиране е споделянето на ключа. За да си комуникират двете страни, те трябва предварително да знаят ключа. В миналото са се извършвали операции по дискретно доставяне на физически ключове до важните организации в света, което е било изключително скъп процес, но и опасен. Бъде ли прихванат ключа, цялата комуникация може да бъде подслушвана. Така се налага ключа, изпращан до човека, с който искаме да комуникираме, също да бъде криптиран с друг алгоритъм. Но какъв ще е ключа за новия криптиращ алгоритъм и как ще бъде предварително споделен?

Асиметрично криптиране

В решаване на този проблем през 70-те години на 20-ти век се разработва асиметричното криптиране. То използва два ключа – публичен и частен. Публичният ключ е известен на всички страни в комуникацията и се използва за криптирането на данните. Изпратените криптирани данни обаче не могат да се декодират с друго освен частния ключ. Частният ключ се знае само от страната получател. Така всеки друг прихванал данните не може да разбере техния смисъл.

Нека разгледаме примера как Ани и Борко ще осъществят поверителна комуникация чрез асиметрично криптиране. Всеки участник в комуникацията притежава частен ключ. Частният ключ е разработен така, че само той да декодира данните от друг ключ – публичния. Ани споделя своя разработен публичен ключ със света. Борко желае да изпрати съобщение на Ани. Той вижда споделения публичен ключ на Ани, използва го да криптира своето съобщение и го изпраща на Ани. Ани получава криптираното съобщение. Само тя знае какъв е нейния частен ключ – само той може да декодира получените съобщения. Ани използва своя таен ключ и разбира съобщението на Борко. Така, ако някой трети човек – Иван, проследи съобщението и има достъп до публичния ключ на Ани, не може да разбере информацията, която Борко ѝ е пратил.[5]

Функция капан

От по-научна гледна точка асиметричното криптиране използва така наречените функции капан. Ако f е функция капан и y = f(x) е лесно за пресмятане, то x = f -1(y) изисква огромно количество изчислителна мощ за пресмятане, освен ако не се знае допълнително, помощно число – k, с което пресмятането на x = f -1(y, k) е тривиално. Така криптирането на дадено съобщение x с публичния ключ, пресмятането на y, е бърза операция, но декриптирането – пресмятането на първоначалното съобщение x чрез криптираното y е почти невъзможно. Но ако човек знае частния ключ – k, възстановяването на x е мигновен процес.[9]

Примерна функция капан е процесът по умножаване на две прости числаp и q. Лесно можем да изчислим колко е тяхното произведение – лесно се смята y = f(p, q). Но обратният въпрос – от дадено y да кажем кои две прости числа са били умножени за получаването на y отнема огромно количество време. Например, трудно ще определим p и q, ако е дадено y = 6895601. Трябва да минем през всяко едно просто число, докато не получим един от делители на y. Но ако получим информация, че p = 1931, то веднага можем да кажем чрез деление колко е другото просто число q. Разбира се, модерните компютри могат бързо да провървят всички прости числа и да намерят делителите на 6895601, но с увеличаването на числото y, тази задача става непосилна за тях.[9]

Хибридно криптиране

Асиметричното криптиране се извършва по-бавно, с повече ресурси отколкото симетричното криптиране. При обмяната на големи количества данни е подходящо да се използва споделен ключ, но как поверително да обменим този ключ? В практиката се използва хибридна версия между двете криптирания. Идеята е споделеният ключ да бъде "договорен" чрез асиметрично криптиране, като се използват частните и публични ключове на двете страни в комуникацията. След като споделеният ключ е предаден тайно, може да се премине към синхронно криптиране.[5]

Хеширане

Основната цел на процеса хеширане е да предостави метод за удостоверяване на източника и интегритета на дадени данни. Това е възможно поради функционалността на хеширането да превръща данни от всякаква големина в низ с константна дължина. Низът, който се получава се казва хеш стойност. Тъй като хеширането е така проектирано, че една хеш стойност да не може да се получи от повече от една уникална съвкупност от данни, то можем бързо да кажем дали съществува промяна в дадени данни. За разлика от криптирането хеширането е необратим процес – не може да се определи стойността преди хеширане чрез хешираната стойност. Ако подаване стойност x на хеширащата функция f, получаваме хешираната стойност y = f(x), но не можем да пресметнем x = f -1(y).

Проверка на интегритет

Нека разгледаме примера, където Борко изпраща съобщение на Ани – файл с много на брой и изключително важни данни. Борко иска да е сигурен, че Ани ще получи целия файл, без някоя информация да се изгуби в процеса на предаване. Борко предварително изчислява хеш стойността на файла и я праща заедно със самия файл. Така, след като Ани получи файла, сама ще изчисли хеш стойността. Ако тя съвпада с тази изпратена от Борко, файлът е бил предаден успешно, ако обаче двете стойности са различни, то нещо се е объркало в процеса по трансфер на данните.

В горния пример ясно се наблюдава едно от основните свойства на хеширането – способността да превръща огромно количество информация в кратък уникален низ, идентифициращ информацията еднозначно. Ако използваме известния алгоритъм SHA-256 за хеширане на даден низ, винаги ще получаваме стойност с дължина 256 бита. При хеширане на низа Аз съм Цезар получаваме 839d8fd51d6fceb3216d35ac8316999264f5d1d1ceb701eb7c488560112df79a. След промяна на дори една буква – Аз съм Сезар, получаваме напълно различна хеш стойност – fc5494b9214f40f96eeb099d14c576962afba000f85c2af6d31a398c3c708121. Така Ани е сигурна, че съобщението е в пълния си вид, когато пристига до нея, и нищо във файла не е било променяно по пътя. Но дали Ани трябва да е толкова сигурна?

Какво ще се случи, ако някой прихване сигнала на Борко и промени файла. След това пресметне новата хеш стойност и изпрати двата файла на Ани. Ани ще провери хеш стойността на получения файл и няма да разбере за подмяната. За да избегнат този проблем Ани и Борко ще използват таен низ, който само те двамата знаят. Борко добавя тайната дума в края на файла, изчислява новия хеш и изпраща първоначалния файл с новата хеш стойност. Когато похитителят подмени файла на Иван и изпрати фалшивите данни със своята хеш стойност, Ани ще забележи подмяната. Когато Ани пресметне хеша на файла, като добави тайната дума в края му, ще получи хеш различен от този на похитителя. Така Ани ще знае, че оригиналният файл е бил подменен. А как Ани и Борко ще се разберат поверително за тайната дума? Разбира се, ще използват асиметрично криптиране.[5]

Хеширане с таен низ

Съхранение на пароли

Способността на хеширането, при малка промяна в първоначалното съдържание напълно да променя хеш стойността в резултата, е ключово свойство за съхранение на пароли. Освен това хеширането не е обратима операция – не можем да разберем първоначалната стойност чрез хешираната. Когато запаметяваме пароли в базата ни от данни, удобно е те да са в хеширан вид. Така, ако хакери получат достъп до базата, не могат да получат достъп до акаунтите на потребителите.

Когато потребителят въведе паролата си за влизане, системата хешира изпратения низ и проверява хешираната стойност, записана в базата. Тъй като две пароли е почти сигурно, че нямат еднакъв хеш, при съвпадение на хешираната стойност, потребителят получава достъп до акаунта си. При въвеждане на хеш стойност в полето за парола, системата отново ще хешира стойността, което ще доведе до нова, различна хеш стойност – достъпът до акаунта ще бъде отказан.

Тъй като хеш стойността е уникална за всяка една парола, хакерите могат да пробват различни пароли и да сравняват получения хеш с този в базата данни. Ако се получи съвпадение, то паролата за акаунта е била налучкана. Хеширането е бавен процес. Съществуват огромни таблици, които съдържат хеш стойностите на статистически най-често използваните пароли.[8] Това позволява на киберпрестъпниците бързо да проверяват възможните пароли с реалните хеш стойности. Генерирането на такива rainbow таблици, включващи всяка възможна комбинация за парола от даден вид, става все по-скъпо с нарастване на дължината на паролата. За това е ключово, когато избираме парола за онлайн система, тя да е дълга и да не съдържа единствено думи.[7]

Посоляване

Проблемът със съхранение на хеширани пароли

Представете си, че вие сте хакерът, който е получил достъп до базата от данни. Разглеждате хешираните стойности и забелязвате два акаунта, на които отговаря един и същи хеш. Знаете, че две различни пароли почти никога не генерират еднаква хеш стойност. Оттук лесно може да се заключи, че повтарящият се хеш отговаря на често използвана парола – последователност от цифри, любим отбор и т.н. Освен това повечето хора използват пароли, които са кратки и лесни за запомняне. По-сигурните пароли с множество символи и голяма дължина са рядко използвани.[7]

За да се решат тези проблеми, модерните системи използват процеса посоляване. Когато потребителят се регистрира в системата, тя създава уникален за него низ от случайни символи. Този низ, наречен сол, се добавя в края на въведената от потребителя парола. След това удължената парола се хешира от системата и се запаметява в базата данни. Така две еднакви пароли ще генерират напълно различен хеш.

Добавяне на сол към парола

Нека си представим, че Ани и Борко се регистрират в сайт. И двамата задават паролата за своят акаунт да е 123456. Хешът на тази парола с известния SHA-256 алгоритъм е b6cfefc9b41b1bd6940e8b023f391bd4ca684a28ab47f9fe86a70d40612e184e. Системата обаче генерира уникални низове за двата акаунта и ги добавя в края на паролите. За Ани низът е @n1x, а за Борко – b0b1. След това системата хешира двата низа 123456@n1x и 123456b0b1, получава двете хеш стойности 0914cd17fb5b89ce55b8b8794f537d446f2587f9b557a73cca01df9c1f4805d4 и a8dd66908bf1c444510fd00a1b78a041f4823ffe4754b82b5e5fc991b28c2684 и ги запаметява в базата данни. Посоляващите стойностите също се запаметяват в базата данни без да се криптират или хешират. Защо?

Когато хакерите отворят базата данни, ще намерят двете хеш стойности и съответните сол стойности. Rainbow таблиците им се оказват безполезни, тъй като никоя от тях не използва добавената сол. Хакерите решават да добавят към всяка популярна парола солта на Борко и започват да пресмятат новите хеш стойности – генерират нова rainbow таблица, което е скъпа операция. Паролата на Борко бива разбита. Сега обаче хакерите трябва да повторят същата операция, като използват солта на Ани. В една система с милион потребители, този процес никога не би бил ефективен.

Всъщност, процесът по посоляване на пароли, използва същата идея, която Ани и Борко приложиха, за да гарантират интегритета на изпратени по мрежата данни – добавянето на таен низ в края на данните преди пресмятането на хеш стойността.

Подлютяване

Солта се съхранява като обикновен текст в базите от данни. Това видяхме, че не е проблем, тъй като всяка парола има уникална сол. Сравнително лесно ще е да разбием един акаунт, но всички – невъзможно. Ако солта беше една за всички акаунти, тогава процеса по разбиване на паролата на Борко, ще разбие всички пароли в системата.

Подлютяването представлява стойност, която е една за цялата система и се добавя в края на всяка една парола. Важната разлика с посоляването е, че стойността за подлютяване не се съхранява заедно с хешираната парола и солта. Обикновено тя е в друг компонент, различен от базата данни. Така, ако престъпниците получат достъп до базата данни, все още няма да имат пълната информация, необходима за разбиването на паролите.[10]

Заключение

Криптирането и хеширането са два есенциални процеса за осигуряване на сигурността в интернет пространството. Криптирането гарантира поверителността и целостта на данните по време на предаване, докато хеширането, особено когато се комбинира с посоляване, предоставя сигурен начин за защита на критични данни като пароли. Чрез използването на двете техники по подходящ начин се осигурява защита на данните и се намалява риска от неоторизиран достъп.

Източници:

  1. The SSL Store, The difference between Encryption, Hashing and Salting, публикувана на 19.12.2018г., [https://www.thesslstore.com/blog/difference-encryption-hashing-salting/]
  2. Wikipedia, Caesar cipher, актуализирана последно на 30.04.2024г., [https://en.wikipedia.org/wiki/Caesar_cipher]
  3. CSFG, Coding - Encryption, Substitution ciphers, посетена последно на 14.05.2024г., [https://www.csfieldguide.org.nz/en/chapters/coding-encryption/substitution-ciphers/]
  4. Simia, How often is which letter?, публикувана на 04.11.2012г., [http://simia.net/letters/]
  5. Practical Networking, Cryptography, посетена последно на 14.05.2024г., [https://www.practicalnetworking.net/series/cryptography]
  6. Google Cloud, What is Encryption?, посетена последно на 14.05.2024г., [https://cloud.google.com/learn/what-is-encryption]
  7. Comparitech, Encryption, hashing, salting - what's the difference?, актуализирана последно на 24.01.2024г., [https://www.comparitech.com/blog/information-security/encryption-hashing-salting/
  8. Cybernews, Hashing vs encryption vs salting: what's the difference?, актуализирана последно на 14.03.2022г., [https://cybernews.com/security/hashing-vs-encryption/]
  9. Wikipedia, Trapdoor function, актуализирана последно на 25.02.2024г., [https://en.wikipedia.org/wiki/Trapdoor_function]
  10. Wikipedia, Pepper (cryptography), актуализирана последно на 07.10.2023г., [https://en.m.wikipedia.org/wiki/Pepper_(cryptography)]
"ТС-ЗСДУИ ЦЙГФИР НУГМ, СХНСОНСХС ЦЙГФ ДИК НУГМ." ~ЩИКГУ