Mój nowy algorytm szyfrujący

0

Na wstępie, chciałbym prosić o pobłażliwość w kwestii błędów ortograficznych w kodzie(np. nazwy zmiennych), w końcu najważniejsza
jest treść a nie forma ortograficzna. Proszę też o pobłażliwość w kwestii licencji, nie znam się na prawie.
A teraz tak: prezentuje mój program szyfrujący, który napisałem trochę niechlujnie, jednak moim celem było jak najszybsze zaprezentowanie samej idei tego algorytmu. Program działa nie do końca dobrze, bo po zaszyfrowaniu i odszyfrowaniu plik jest nieco większy o kilka bajtów. To jedna sprawa a druga: czy taki algorytm szyfrujący już istnieje? Pytam bo nie wiem za bardzo wiem jak to sprawdzić. Większość moich programów dostępnych jest pod adresem tworczoscgorskiego.cba.pl

/*
Licencja: pozwalam używać tego programu pod warunkiem że będzie wykożystywany w celach niekomercyjnych jak również 
w celach niekomercyjnych będą wykorzystywane wszystkie jego metody
szyfrowania w nim zawarte jeśli ktoś będzie chciał wykorzystywać ten program lub metody mojego autorstwa w nim zawarte 
komercyjnie może to zrobić jednak musi mi za to zapłacić cena do uzgodnienia można się ze mną 
skontaktować pod numerem 518242320 lub mailem [email protected] 
copyright Marcin Górski 2016
*/
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>

using namespace std;
void zrubmio(int * m,int * o)
{
	 do{
		*m = rand()%32000;
            if(rand()%2)*m = - *m;
		*o = rand()%32000;
            if(rand()%2)*o = - *o;	
			
	}while( !((*m) && (*m != *o) && (*m != -(*o)) &&(*o)) );
} 
		
struct pakiet{
	long int dane;
	long int mnoznik;
	long odejmning;
	void pisz()
	{
		cout<<"dane "<<dane<<endl<<" monoznik"<<mnoznik<<endl<<"odejmnig"<<odejmning<<endl;
	}
};

int main(int argc,char* argv[])
{
	pakiet pakiecik;	
	int m,o,m2,o2,t,reszta,temp2;
	int rozmiarz;
	long int temp;
	int cp=24;

	string parametr="-c";
	string parametr2="-e";
	if(argc < 6)cout<<"używanie szyfrgorskiego parametr -c dla szyfrowania -e lda odszyfrowania plik wejsciowy \n plik wyjsciowy liczba od -32000 do 32000 i jeszcze jedna taka \n np. szyfrgorskiego -c obrazek.png zbiur 231 30021 lub szyfrgorskiego -e zbiur odszyfrowane.png 231 20021"<<endl;
                
	ifstream zpliku(argv[2],ios::binary);

	zpliku.seekg(0,ios::end);
	rozmiarz =zpliku.tellg();
	zpliku.seekg(0,ios::beg);
	reszta=rozmiarz % 4;
	ofstream dopliku(argv[3],ios::binary | ios::trunc);

	istringstream ms(argv[4]);
	istringstream os(argv[5]);
	ms>>m;
	os>>o;
	
	if(m<(-32000) || m > 32000 || o<(-32000) || o > 32000)
	{
		cout<<"zle prametry"<<endl;
		return 1;
	}
	if(!zpliku){
		cout<<"blad pliku wejsciowego"<<endl;
		return 1;
	}
	if(!dopliku){
		cout<<"blad pliku wyjsciowego"<<endl;
		return 1;
	}	
	if(parametr==argv[1])
	{
		cout<<"szyfruje"<<endl;
		
		pakiecik.mnoznik=reszta;
                char* wsk =(char*)(&pakiecik.dane);
		wsk="grs";
		dopliku.write((char*)&pakiecik,cp);
int i=0;		
		while(zpliku)
		{
			//cout<<"obieg"<<i++<<endl;
			
			zpliku.read((char*)&temp,4);
			pakiecik.dane=m*temp-o;
			zrubmio(&m2,&o2);
			pakiecik.mnoznik=m*m2-o;
			//if(!m2)m2=pakiecik.mnoznik=m*4-o;
			pakiecik.odejmning=m*o2-o;
			m=m2;
			o=o2;
			if(m==0 || o==0 || m==o || m== -o)cout<<"zle"<<endl;
			dopliku.write((char*)&pakiecik,cp);
			if(reszta && zpliku.tellg()==rozmiarz-reszta)
			{
				zpliku.read((char*)&temp,reszta);
				pakiecik.dane=m*temp-o;
				dopliku.write((char*)&pakiecik,cp);
			}
                        //cout<<"obieg"<<i<<endl;
		}
	return 0;
	}else if(parametr2==argv[1])
		{
			cout<<"odszyfrowuje"<<endl;
			zpliku.read((char*)&pakiecik,cp);
			reszta=pakiecik.mnoznik;

			while(zpliku)
			{
				zpliku.read((char*)&pakiecik,cp);
				//pakiecik.pisz();
				temp2=(pakiecik.dane+o)/m;
				m2=(pakiecik.mnoznik+o)/m;
				o2=(pakiecik.odejmning+o)/m;
				m=m2;
				o=o2;
				dopliku.write((char*)&temp2,4);
				if(reszta && (zpliku.tellg() == rozmiarz-4))
				{
					zpliku.read((char*)&pakiecik,cp);
					temp2=(pakiecik.dane+o)/m;
					dopliku.write((char*)&temp2,reszta);
				}
			}
		return 0;
		}
return 1;
}
				


 

Z góry dziękuję za wszelką pomoc i jeszcze raz przepraszam, za straszny niechlujny kod.
Marcin Górski

4

Ale że w sumie na co tak właściwie liczysz?

Bo nie wiem czy próbujesz się pochwalić algorytmem szyfrowania, który wygląda na zwyczajny szyfr przestawieniowy, czy może prosisz o porady w sprawie formatowania kodu oraz korzystania ze słownika.

1

Że tak zacytuję:
"Skąd się biorą tacy głupcy?"

0

Klucz do odszyfrowania zapisujesz w pliku zaszyfrowanym.
Słowo "szyfr" jest tu trochę na wyrost - raczej podszedłbym do tego jako do wprawki na temat bezpieczeństwa.

Poza tym przekształcenie liniowe:
f(x) = a*x - b

nie jest jakimś specjalnie rozbudowanym algorytmem.

0

Tu nie chodzi tylko o to że mnożymy i odejmujemy lecz o to że każdy następny pakiet jest szyfrowany innymi losowymi wartościami
i ja się pytam czy takie coś już jest być może jest w takim racie ameryki nie odkryłem to przepraszam za kogo ja się uważałem
chyba rzeczywiście za mądry nie jestem przepraszam
tak czy inaczej mam pytanie czy łatwo takie coś złamać bo mi się wydaje że nawet znając część danych takie coś jest niełatwe
i tak w ogóle to dobrze się stało że piszą o mnie głupiec to będzie dobrze dla mojej pokory

3

Tu nie chodzi tylko o to że mnożymy i odejmujemy lecz o to że każdy następny pakiet jest szyfrowany innymi losowymi wartościami
Tak - ale de facto jedyne przekształcenie które wykonujesz, to mnożenie oraz dodawanie.

mam pytanie czy łatwo takie coś złamać bo mi się wydaje że nawet znając część danych takie coś jest niełatwe
Wystarczy znać algorytm - security by obscurity nie jest ratunkiem :P

0

Tryby szyfrowania są tutaj: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
Prawdopodobnie któryś do twojego pasuje

3
dreammaker napisał(a):

Tu nie chodzi tylko o to że mnożymy i odejmujemy lecz o to że każdy następny pakiet jest szyfrowany innymi losowymi wartościami

Z tym losowaniem to bym nie przesadzał. Po pierwsze std::rand() jest całkowicie nieodpowiednia do zastosowań kryptograficznych. Po drugie ten program zawsze używa dokładnie tych samych liczb, ponieważ nigdzie nie ma std::srand().

6

Program działa nie do końca dobrze, bo po zaszyfrowaniu i odszyfrowaniu plik jest nieco większy o kilka bajtów

To chyba jednak duży problem. Czyli jeśli ktoś zaszyfruje za jego pomocą plik, potem odszyfruje, to nie będzie mógł go otworzyć? ;) (niektóre formaty są wrażliwe, i zmiana nawet jednego bajta może spowodować kompletne uszkodzenie całego pliku).

A po drugie - nawet gdyby działał, to ten szyfr jest niestety kompletnie bezużyteczny, w tym sensie, że można go trywialnie złamać za pomocą prostej kryptanalizy. Nie patrzyłem dokładnie, ale na oko mając do dyspozycji tylko zaszyfrowany plik (z sensownymi danymi, np. plaintextem) można łatwo go zdeszyfrować.

Już nie mówiąc że, po trzecie, rand() ma cztery bajty entropii, więc nawet pomijając punkt 2, można zrobić bruteforce na wszystkich możliwych seedach (ale i tak nie ma sranda, więc entropia tutaj wynosi zero).

Ogólnie nie chcę być pesymistyczny, ale pisanie własnych algorytmów szyfrujących bez doktoratu z kryptografii mija się z celem.

0

ten program miał tylko zaprezentować mój pomysł tak myślałem że jest tak z rand() jak mówicie jednak nawet znając część danych nie tak łatwo moim zdaniem jest obliczyć zmienne o i m bo zobaczcie m * x - o = x_poszyfrowaniu 2 niewiadome i tylko 1 równanie a drugiego równania nie ma ponieważ następne o i m są losowe.

7

Zabezpieczenie o sile 30.5b, do złamania brute force w góra kilka godzin na przeciętnym sprzęcie. Jeśli znasz część danych, to brute force zajmie kilka minut. Plus jest taki, że zaszyfrowana wiadomość nie podda się analizie statystycznej.
Random z dwóch liczb losowany aż do skutku (obie różne od zera i od siebie).
Trzykrotne rozdmuchanie rozmiaru pliku wynikowego.
Kod źródłowy tragiczny, błędy ortograficzne i literówki (acz za odejming masz u mnie piwo, bo mnie rozbawiła ta nazwa; czyżby miał być odjemnik?), bardzo słabe formatowanie, polskie nazwy zmiennych, brak podziału na funkcje. W sumie to brak podziału na cokolwiek, taki spaghetti-code.
Niewykorzystanie pełnego zakresu 16b, dodatkowe losowanie znaku - znacznie prościej byłoby wylosować te m i o z zakresu 1-65535, a potem działać na zmiennych bez znaku.
Dwukrotne losowanie (raz liczby, drugi raz jej znaku) nie zwiększa w żaden sposób losowości.
Brak zainicjowania generatora liczb losowych, o czym wspominali przedmówcy, kompletnie dyskwalifikuje tą konkretną implementację Twojego pomysłu, ponieważ znając algorytm działania generatora liczb pseudolosowych i jego stan początkowy będzie można odszyfrować wiadomość bez brute force.

Podsumowując - pomysł w miarę fajny, implementacja bardzo słaba.

3
dreammaker napisał(a):

ten program miał tylko zaprezentować mój pomysł tak myślałem że jest tak z rand() jak mówicie jednak nawet znając część danych nie tak łatwo moim zdaniem jest obliczyć zmienne o i m bo zobaczcie m * x - o = x_poszyfrowaniu 2 niewiadome i tylko 1 równanie a drugiego równania nie ma ponieważ następne o i m są losowe.

Jak już ustaliliśmy ze względu na brak zainicjowania generatora liczb pseudolosowych następne o i m nie są losowe, będą pomnożone / powiększone o znane wartości.
Jeśli znamy oryginalną wartość pierwszego longa zaszyfrowanych danych, to od razu mamy m i o, niezależnie od użycia srand. Akurat tak się składa, że pierwsze bajty dla dużej ilości formatów plików zawierają predefiniowane nagłówki, np. dla .zip to PK\3\4.
Bez srand, o ile dobrze myślę (nie jestem w 100% pewien), to po góra 64 mnożeniach przez parzyste liczby oryginalne, wprowadzone przez użytkownika m zniknie, dalej będą już tylko wartości z rand. Znając od pewnego momentu kolejne wartości m resztę danych - o ile znamy ich typ - można poddać analizie statystycznej, a zresztą o ma tylko niecałe 16b, więc brute-force dalszych danych będzie banalny. Znając o można przystąpić do brute-force'a m, dzięki czemu odszyfruje się także pierwsze kilkadziesiąt bloków danych.

Profesjonalne algorytmy szyfrujące i hashujące nigdy nie korzystają ze zwykłego mnożenia, przeważnie masz potęgowanie modulo i/lub xor i przesunięcia bitowe - to wszystko po to, żeby nie zatrzeć klucza. Ponadto przyjętym przez kryptologów kryterium szyfrowania dobrej jakości jest taka definicja: zmiana dowolnego jednego bitu klucza szyfrującego zmieni średnio połowę bitów zaszyfrowanych danych. Twój algorytm nie jest nawet blisko spełnienia tego kryterium.

1 użytkowników online, w tym zalogowanych: 0, gości: 1