LINUX.ORG.RU

Код на C++ (шифр Вернама) выполняется не совсем корректно, как исправить?

 ,


0

1

Здравствуйте!

Есть код на C++ (реализация идеи симметричного шифрования Гилберта Вернама), компилируется без ошибок, в принципе - даже работает, если бы не одно но:

Корректная работа программы возможна только при следующих условиях:

  • в сообщении допустимо использовать только заглавные латинские буквы (без пробелов);
  • в ключе допустимо использовать только цифры и заглавные латинские буквы;

При соблюдении этих условий, код работает корректно.

Но хотелось бы всё-таки научить его кириллице, знакам пунктуации, регистру.

Возможно ли без изменения всей логики в целом? Если да, то как?


Программа алгоритма шифрования:


#include<bits/stdc++.h>
using namespace std;

int main(){
    int t,n,i,j,k,sum=0;
    string m;
    cout<<"Enter the message"<<'\n';
    cin>>m;
    string key;
    cout<<"Enter the key"<<'\n';
    cin>>key;
    int mod = key.size();
    j=0;
    for(i=key.size();i<m.size();i++){
        key+=key[j%mod];
        j++;
    }
    string ans="";
    for(i=0;i<m.size();i++){
        ans += (key[i]-'A'+m[i]-'A')%26+'A';
    }
    cout<<"Encrypted message: "<<ans<<'\n';
    
    return 0;
}


Пример работы:


$ ./en
Enter the message
LINUX    
Enter the key
LORORGRU
Encrypted message: WWEIO

Программа алгоритма дешифрования:


#include<bits/stdc++.h>
using namespace std;

int main(){
    int t,n,i,j,k,sum=0;
    string m;
    cout<<"Enter the message"<<'\n';
    cin>>m;
    string key;
    cout<<"Enter the key"<<'\n';
    cin>>key;
    int mod = key.size();
    j=0;
    for(i=key.size();i<m.size();i++){
        key+=key[j%mod];
        j++;
    }
    string ans="";
    for(i=0;i<m.size();i++){
        ans += (m[i]-key[i]+26)%26+'A';
    }
    cout<<"Decrypted message: "<<ans<<'\n';
    
    return 0;
}


Пример:


$ ./de
Enter the message
WWEIO
Enter the key
LORORGRU
Decrypted message: LINUX

Источник: https://japp.io/cryptography/vernam-cipher-algorithm-program-in-c-c/


Компиляцию выполнял следующим образом (debian 11):


$ g++ en.cpp -o en

$ g++ de.cpp -o de


Запуск в терминале:



$ ./en

$ ./de


Также интересует мнение относительно криптостойкости данной реализации.



Последнее исправление: LinuX (всего исправлений: 1)

только заглавные латинские буквы

%26

*this, расширяйте алфавит до 6и бит

Но хотелось бы всё-таки научить его кириллице, знакам пунктуации, регистру.

Кодируйте-декодируйте в base64

относительно криптостойкости данной реализации.

for(i=key.size();i<m.size();i++){
        key+=key[j%mod];

*this.

Для абсолютной криптографической стойкости ключ должен обладать тремя критически важными свойствами[2]:
Иметь случайное дискретное равномерное распределение
Совпадать по размеру с заданным открытым текстом

Ви эти условия нарушаете, дописывая ключ.

thunar ★★★★★
()
Последнее исправление: thunar (всего исправлений: 3)
Ответ на: комментарий от thunar

Ви эти условия нарушаете, дописывая ключ.

Тогда уже вообще про шифр Вернама скажи.

Видно же, что у ТС учебное задание. Скорее всего на изучение C++. Не PBKDF2 же ему писать в самом деле =)

praseodim ★★★★★
()
Ответ на: комментарий от praseodim

Спасибо! В целом понял, но с реализацией на С++, боюсь, будут сложности. Может тогда попытаться доработать этот вариант? https://habr.com/ru/company/ua-hosting/blog/270931/

Вообще, изначально цель - организовать защищенный канал связи для крайне узкого круга лиц. Вполне возможно, что есть и более логичные способы. Но децентрализованные мессенджеры работают нестабильно. Как по мне, идеальный вариант - тот же Telegram + свой велосипед.

LinuX
() автор топика
Ответ на: комментарий от LinuX

цель - организовать защищенный канал связи для крайне узкого круга лиц

Ты же в курсе, что одноразовый блокнот является абсолютно устойчивым шифром только если гамма всегда одноразовая? Если гамма переиспользуется, то такой шифр сразу же становится одним из наименее безопасных.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Спасибо за предупреждение!

В этом плане думаю заготовить файл с ключами, которых бы хватило на годы вперед и передать их безопасным способом.

Еще такой момент:


Длина гаммы должна быть не меньше длины защищаемого сообщения (открытого текста). В противном случае для получения открытого текста потребуется подобрать длину гаммы, проанализировать блоки шифротекста угаданной длины, подобрать биты гаммы.

Я же правильно понимаю, что допускается, чтобы длина ключа была больше длины защищаемого сообщения? Если да, то насколько больше?

LinuX
() автор топика
Ответ на: комментарий от LinuX

В этом плане думаю заготовить файл с ключами, которых бы хватило на годы вперед и передать их безопасным способом.

Это не так просто сделать как кажется, если хочется действительно что-то надежное. И заготовить и передать и использовать.

В общем, лучше применить что-то известное и стандартизированное. aes с алгоритмом формирования ключа по парольной фразе вроде pbkdf2 или argon2 неплохой выбор. Такое, если не допустить ошибок реализации, если кто и сломает, то разве что такие «дяди», что надо очень-очень-очень постараться, чтобы привлечь их внимание.

praseodim ★★★★★
()
Ответ на: комментарий от vvn_black

Но ведь это библиотека, а не готовое приложение. :(

К тому же, её применение предполагает достаточно высокий уровень квалификации. Мне бы что-то простое и понятное. И безотказное.

LinuX
() автор топика
Ответ на: комментарий от LinuX

Спасибо! В целом понял, но с реализацией на С++, боюсь, будут сложности. Может тогда попытаться доработать этот вариант? https://habr.com/ru/company/ua-hosting/blog/270931/

Не хочу обижать, но просто объективные вещи говорю. Если для вас реализовать что-то такое на C++ - это «сложности», то боюсь и вообще за слишком сложное дело беретесь. Уровень владения необходим такой, что вас должно волновать не как это написать на C++ или на каком еще языке, а насколько надежно что-то и какие есть подводные камни.

Разве что как упражнение в программировании, что пока делаете и учитесь, но использовать результат таких трудов на практике вряд ли стоит.

Если проблема только в C++, пишите на более хорошо изученном языке по поводу которого вопросов как написать не будет.

Вообще, изначально цель - организовать защищенный канал связи для крайне узкого круга лиц.

praseodim ★★★★★
()
Последнее исправление: praseodim (всего исправлений: 2)
Ответ на: комментарий от LinuX

Мне бы что-то простое и понятное.

Вот, от гугла, кроссплатформенно, разные ЯП, примеры, всё как все любят - https://github.com/google/tink

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)

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

Подумайте, к примеру, вы сможете контролировать, кто «стоит за спиной» у каждого члена вашей группы и считывает сообщения с экрана?

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)
Ответ на: комментарий от vvn_black

Согласен, что сколь либо сложная система шифрования бессмысленна, если имеется физический доступ к персоне. Ну здесь немного не тот случай.

LinuX
() автор топика
Ответ на: комментарий от LinuX

защищенный канал связи для крайне узкого круга лиц.

Любой незащищённый канал связи + асимметричное шифрование с достаточно длинным ключём. Тот же жаббер ЕМНИП позволяет подключить gpg ключ плюгином. Если уж совсем заморочиться — можно обновлять ключ на каждое новое новое сообщение — и передавать открытую часть в том же письме.

thunar ★★★★★
()
Последнее исправление: thunar (всего исправлений: 2)
Ответ на: комментарий от LinuX

Но децентрализованные мессенджеры работают нестабильно.

Может тогда заняться повышением их стабильности? Велосипедов и так уже нарожали.

Дело твоё, конечно.

hobbit ★★★★★
()

Также интересует мнение относительно криптостойкости данной реализации.

Криптостойкость - это свойство алгоритма, а не реализации. В контексте реализации принято говорить о уязвимостях, которые могут и не иметь никакого отношения к алгоритму шифрования/дешифрования. О криптостойкости ш. Вернама написано в вики.

seiken ★★★★★
()
Ответ на: комментарий от hobbit

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

А вообще, может к тому времени кто-то из профи озадачится вопросом и напишет свою реализацию. Всё таки информационная безопасность - это не та область, где можно создавать что-то методом научного тыка. Хотя бы потому, что уязвимости не так явно видны, как например, неправильная работа какого-нибудь Front-End скрипта.

LinuX
() автор топика
Ответ на: комментарий от LinuX

Всё таки информационная безопасность - это не та область, где можно создавать что-то методом научного тыка.

Здраво.

Но мой посыл был в том, что недоделанных поделок в софте (не только в открытом) много. Причём когда они недоделанные и заброшенные — это полбеды, хуже когда доделанное выдаётся за готовое. Поэтому в большинстве случае полезнее не начинать очередной велосипед, а присоединиться к существующему проекту и постараться его улучшить.

Плохая новость: это действительно НАМНОГО сложнее, чем с радостью первопроходца начинать с нуля, и на первых этапах руки могут просто опуститься. Хорошая новость: гораздо меньше шансов потом сожалеть на время, потраченное на очередной чемодан без ручки. Ну и изучать чужие исходники и задаваться вопросом «А как это вообще работало» бывает прикольно и увлекательно, чего уж.

И если к децентрализованным мессенджерам у тебя претензии действительно именно по стабильности — почему бы и не залезть в эту тему?

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 2)

Вот чем плохо обучение в вузах бСССР - это тем, что там пичкают мозги какой-то нерелеватной херотой. Типа шифра вермана и чтоб обязательно на C++. И чтобы написать самому.

Потом на работе придется все эти знания из головы выкинуть, и использовать PBKDF2, RSA и AES, и в виде готовых решений.

lovesan ★★
()