Crazy encrypting algo

Pages: 1234
Emil Enchev I think you're right.

I print "||||||||||||||" when my uncrypt algo see the '\0' char, and I got something like.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
clear text
*/
||||||||||||||||||||||
||||||||||||||||||||||
||||||||||||||||||||||
||||||||||||||||||||||
/*
bug text
*/
||||||||||||||||||||||
||||||||||||||||||||||
||||||||||||||||||||||
||||||||||||||||||||||
/*
bug text again
*/
etc...


So the problem appear at the exact same location of the '\0' spam.

However I'm still looking on how to fix it.
Last edited on
I print "||||||||||||||" when my uncrypt algo see the '\0' char, and I got something like.


Can you make this time code that not print but that SKIP OVER decrypt procedure when see '\0' keeping the key for the next character?

You want to see if the problem is with SHIFTING of KEYS.

P.s.
I tried to set my keys to 0, and so it works in this case.

You can set your keys to 1 (11111111), or 2(22222222) or any repeating two digits number 12121212, 53535353 if you want and it will work again, because it is problably shifting keys problem.
Last edited on
Actually when dealing with binary data it isn't a good idea to use std::string. Instead use std::vector<char>. You can easily convert it back to a string when you are sure that it is text.

E.g.:
1
2
3
std::vector<char> v;
...
std::string s{v.begin(), v.end());


You may use copy:
1
2
3
std::vector<char> v;
...
        if(n=recv(s,buff,bufsize,0)) std::copy(buff, buff + n, std::back_inserter(v));
coder777, I also think that using std::string is not good idea when '\0' appear. But I don't understand much.

1
2
3
4
5
6
7
8
9
#include <iostream>

int main()
{
	// '\0' cut string
	std::string str{ "I'm\0 man!" };
	std::cout << str << std::endl;
	std::cout << str.size() << std::endl;
}


Zaap, Inform us about your progress.
Last edited on
I tried all the morning until now to fix it, but I didn't.

I hesitate to just block the possibility to overpass the bufsize limit (my server isn't supposed to send big data) but that would be a garbage method.

What I tried was:

1) Remove all the '\0' except the last of the final string.
Unfortunatly some disappear but not all, so the key-shift problem persist.

2) Uncrypt sub messages first and then concat them.
Not working too, don't really know why.

3) Convert my string as vector<char>.
The problem of the key-shift is still here so can't do anything with that.

You can set your keys to 1 (11111111), or 2(22222222) or any repeating two digits number 12121212, 53535353 if you want and it will work again, because it is problably shifting keys problem.


Do you try this above please, and tell me result. If you don't have problem with symmetric keys like 11111111 or 53535353 you with sure will know that it is shifting problem. Next will think further. But don't use mixed codes in one time. If you chose 11111111, all keys must be 11111111, or if you chose 53535353, all other keys must be 53535353.

P.s. Next try to SKIP OVER '\0' when you UNCRYPT, so the key not apply to '\0' but to next sign in message, not to remove them - and also tell me result.

1. Are you CRYPT '\0' with keys in original messages?
2. How many '\0' you have usually when you receive whole message, and how many '\0' you have when you receive two fragment messages?
Last edited on
I tried with keys like 53535353 and it worked fine.

When I said "remove", I mean skip it and remove one to my "i" during the uncrypt loop to maintain the good shift. (I also tried several different method but nothing worked).

I counted all the once '\0' and I got something like 13 + 8.
It is really not that complicated:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/** Receive a message */
std::string msgr(SOCKET s, const bool& show=true){
    diffhell dh;
    char buff[bufsize];
    std::string str="";
    std::vector<char> v;
    int n(bufsize);
    bool noResponse(false);
    while(n!=SOCKET_ERROR && n>=bufsize && !noResponse){
        if(n=recv(s,buff,bufsize,0)) for(int i(0);i<n;++i) str+=buff[i];
        if(n=recv(s,buff,bufsize,0)) std::copy(buff, buff + n, std::back_inserter(v));
        else noResponse=true;
    }
    std::string str="";
    if(::CRYPTED) str=dh.uncrypt(::MY_KEY,::MY_KEY2,::MY_KEY3,::MY_KEY4,v);
    if(::CRYPTED) str=dh.uncrypt(::MY_KEY,::MY_KEY2,::MY_KEY3,::MY_KEY4,str);
    bool write(false);
    while(!write){
        fstream file("log.txt");
        if(file.is_open()){
            file.seekp(0,ios::end);
            file<<str<<"\n";
            write=true;
        } else{
            system("title>>log.txt");
        }
    }
    if(str.size()<5 || !(str.substr(0,2)=="__" && str.substr(str.size()-2,2)=="__")) std::cout<<"<from>"<<str<<std::endl;
    return str;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
std::string uncrypt(const uint64_t& key, const uint64_t& key2, const uint64_t& key3, const uint64_t& key4, std::string msg){
std::string uncrypt(const uint64_t& key, const uint64_t& key2, const uint64_t& key3, const uint64_t& key4, const std::vector<char>& msg){
        std::string tk(to_string(key)+to_string(key2)+to_string(key3)+to_string(key4)); //text key
        vector<int> tmp_tk;
        if(tk.size()%2!=0) tk+=tk[0];
        while(tk.size()>0){
            tmp_tk.push_back(atoi(tk.substr(0,2).c_str()));
            tk=tk.substr(2);
        }
        for(int i(0);i<tmp_tk.size();++i) tk+=(char)tmp_tk[i];
        while(tk.size()<msg.size()){
            tk+=tk;
        }

        if(msg.size()<=tk.size()){
            std::string tmp="";
            for(int i(0);i<msg.size();++i){
                char tmp_val=msg[i]-tk[i];
                if(tmp_val<-127) tmp_val+=255;
                tmp+=tmp_val;
            }
            return tmp;
        }
    }


For vector see:

http://www.cplusplus.com/reference/vector/vector/?kw=vector

It is a ver commonly used container.

For back_inserter see:

http://www.cplusplus.com/reference/iterator/back_inserter/
I know what is a vector and how to use it, the problem I have is about the shift of the key during uncrypt loop when I try to skip the "\0".
I tried with keys like 53535353 and it worked fine.


So, it is defiantly SHIFTING PROBLEM!

When I said "remove", I mean skip it and remove one to my "i" during the uncrypt loop to maintain the good shift. (I also tried several different method but nothing worked).


Its not working, because you have some GOOD '\0's between BAD '\0's that you must NOT SKIPPED during UNCRYPT phase.

I counted all the once '\0' and I got something like 13 + 8.


That was many '\0's :-)

Are your Crypt code, deal with '\0' in proper way, i.e. fuck them(remove them from the message) when he encounter one during encrypting phase?


Is there possibility that you encrypt some symbol "z"+ key = 0 in first place?

This can lead to unpredictable behavior from transfer protocol side if it have spacial way to dealing with '\0'.

Can you rearrange your code to use vector<char> container, as coder777 advise you, and to remove all '\0' from Encrypting process, so to reduce their numbers?

For example, when you know that your Encrypt algo not lead to producing of '\0's and not encrypt '\0's, and every zero is trash, you can deal with problem easy.
Last edited on
I tried to replace the char encrypted as '\0' by a dot (so normally there is no bad '\0' into the crypted string, but the problem is persisting.

I also replaced my string by a vector but it does exactly the same.
Zaap,

1. Make one big message, consist only from 1111111111111111111111111.....
2. Encrypt it with keys 12131213.
3. Decrypt it and see result

Original - Keys - Encrypt message
1 1 1 1 1 1 1
12 13 12 13 12 13 12
13 14 13 14 13 14 13


Encrypt message with parasite '\0' inside - decrypt Keys - Result message
13 14 00 13 14 13 14
12 13 12 13 12 13 12
1 1 242 0 2 0 2

Can you see for me, is there such pattern?

P.s. I know 1 don't have Ascii code 1, but this is only for illustration. I want to see what is pattern after decrypt.

1. The points of changing patterns 1111... to 0202... and 0202... to 1111.. are your parasite '\0'. Count their numbers.
2. Count '\0' numbers too.

If '\0' numbers are more than points of changing of patterns, this mean you have BAD and GOOD '\0'.

P.p.s. Do you know that Big software firms sometimes hire programmers to search for a specific bug, and often this bug can be searched for 6 months? :-) Think about it.
Last edited on
I tested the following :

My file contain 100 000 "1".

Keys :
1 - 01
2 - 02
3 - 01
4 - 02
So concat key is 01020102

Crypt expected : 232323232323...
I've got : ============...

Decrypt : I've got 11111 (so all good).

So.... I don't understand.

PS : My original file used for the tests works too, but when the key is generated, it doesn't.

Second test :

Keys become :
1 - 01020102
2 - 02030203
3 - 03040304
4 - 04050405

And there is the bug. (A pattern is clearly visible of course).
Last edited on
Crypt expected : 232323232323...


Why?! '1' Ascii is 049

If you use key 01 and 02 are you don't expect

Crypt expected : 505150515051?!

Now you try Keys
1-01
2-02
3-03
4-04
So contact key is 01020304, and use only this key, again only on file contain 100 000 "1".

Question: How many concat keys you use for encoding of one file?

I also replaced my string by a vector but it does exactly the same.

This is not matter. Vector is better and secured option here. I even amuse how you deal with string and '\0's in the middle, as I show you they cut string - so many things I must learn about this C++ language?!
Last edited on
My key is 01 02 01 02
So "1 1 1 1" becomes
'1'+(01) -> '2'
'1'+(02) -> '3'

So "2 3 2 3" (without space).

I was talking about the char symbol, not the int value behind the char symbol.

Edit : '=' ascii code is 51, so the exact value added is 12. Is that a coincidence ?
(01) (02) -> (1) (2) -> 12

Edit 2 : 01030103 give >>>>> so no it's not a coincidence, there is something wrong here.
Last edited on
I use 4 keys that I concat in one big key (this is for some technical reasons).

Note : my encryopting message end with the alt+23 (↨) char. I don't know from where appear this one.

Test with concat-key : 01020304
Encrypted message : S=S=S=S=... end with ','
No bug detected.

Edit : I'll be back tomorrow.

Edit 2 : I know why there is a +12 instead of +1 +1, it's cause I concat using to_string(KEY1) so to_string(01)+to_string(02) becomes to_string(1)+to_string(2), so "12".
Last edited on
Read next...
Last edited on
Read next...
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <vector>
#include <string>
using namespace std;
std::string uncrypt(const uint64_t& key, const uint64_t& key2, const uint64_t& key3, const uint64_t& key4, std::string msg) {
	std::string tk(to_string(key) + to_string(key2) + to_string(key3) + to_string(key4)); //text key
	vector<int> tmp_tk;
	if (tk.size() % 2 != 0) tk += tk[0];
	while (tk.size() > 0) {
		tmp_tk.push_back(atoi(tk.substr(0, 2).c_str()));
		tk = tk.substr(2);
	}
	for (int i(0); i < tmp_tk.size(); ++i) tk += (char)tmp_tk[i];
	while (tk.size() < msg.size()) {
		tk += tk;
	}

	if (msg.size() <= tk.size()) {
		std::string tmp = "";
		for (int i(0); i < msg.size(); ++i) {
			char tmp_val = msg[i] - tk[i];
			if (tmp_val < -127) tmp_val += 255;
			tmp += tmp_val;
		}
		return tmp;
	}
}


std::string crypt(const uint64_t& key, const uint64_t& key2, const uint64_t& key3, const uint64_t& key4, std::string msg) {
	std::string tk(to_string(key) + to_string(key2) + to_string(key3) + to_string(key4)); //text key
	vector<int> tmp_tk;
	if (tk.size() % 2 != 0) tk += tk[0];
	while (tk.size() > 0) {
		tmp_tk.push_back(atoi(tk.substr(0, 2).c_str()));
		tk = tk.substr(2);
	}
	for (int i(0); i < tmp_tk.size(); ++i) tk += (char)tmp_tk[i];
	while (tk.size() < msg.size()) {
		tk += tk;
	}

	if (msg.size() <= tk.size()) {
		std::string tmp = "";
		for (int i(0); i < msg.size(); ++i) {
			char tmp_val = msg[i] + tk[i];
			//if (tmp_val < -127) tmp_val += 255;
			tmp += tmp_val;
		}
		return tmp;
	}
}
int main()
{
	std::string msgO{ "1111111111" };
	uint64_t key = 1212;
	uint64_t key2 = 1212;
	uint64_t key3 = 1212;
	uint64_t key4 = 1212;
	std::string msgC{ crypt(key, key2, key3, key4, msgO) };
	std::string msgU{ uncrypt(key, key2, key3, key4, msgC) };

	cout << "Original Message: "<< msgO << endl;
	cout << "Crypt Message: " << msgC << endl;
	cout << "Ucrypt Message: " << msgU << endl;
}



Original Message: 1111111111
Crypt Message: ==========
Ucrypt Message: 1111111111
Last edited on
Look Zaap, whatever misunderstanding you have with your encryption and decryption algorithm it works as I expected.


Keys :
1 - 01
2 - 02
3 - 01
4 - 02
So concat key is 01020102


Your concat key in above case is not 01020102, but 1212. Your algorithm simply eat the 0's in front of 01 to 09.

uint64_t key = 01020102; is equal to this uint64_t key = 270402;

When you put 0 in front of int number, compiler think it as OCT number and make implicit conversation: 0 "Hmm, it is OCT" so 1020102 = int 270402; You are not able to make concate key starting with mini-key 01(02...) and put it in unit64_t. Of course you can make 01 in second mini-key position 1101 and next ones, but never in first. If you use string instead unit64_t, it will be ok.

This ban, of course, does not apply to the combined keyAll = key + key2 + key3+key4


        uint64_t key = 0;
	uint64_t key2 = 1;
	uint64_t key3 = 0;
	uint64_t key4 = 2;


This will give keyAll = "0102" starting with 01. And from 111111... you to have your 232323... result.


Original Message: 1111111111111111111111111111111111
Crypt Message: 2323232323232323232323232323232323
Ucrypt Message: 1111111111111111111111111111111111


This is also not true:


Keys become :
1 - 01020102
2 - 02030203
3 - 03040304
4 - 04050405


Your real keys are:
1 - 1212
2 - 2323
3 - 3434
4 - 4545

But this is not matter if your crypt and uncrypt function used the same keys! This is only problem of your understanding of keys forming process.


My key is 01 02 01 02
So "1 1 1 1" becomes
'1'+(01) -> '2'
'1'+(02) -> '3'

So "2 3 2 3" (without space).

I was talking about the char symbol, not the int value behind the char symbol.

Edit : '=' ascii code is 51, so the exact value added is 12. Is that a coincidence ?
(01) (02) -> (1) (2) -> 12

Edit 2 : 01030103 give >>>>> so no it's not a coincidence, there is something wrong here.


Here you don't have


'1'+(01) -> '2'
'1'+(02) -> '3'


but as I said

'1'+12
'1'+12

Ascii for '1' is 049. So you add 49 + 12 with result 61 which is exactly "=" symbol.

I was talking about the char symbol, not the int value behind the char symbol.


Not you working exactly with int values behind the char symbols.

'1'+1 != '2' but '1'+1 = 50 which is the int value of '2'

Edit 2 : 01030103 give >>>>> so no it's not a coincidence, there is something wrong here.


The same case. Your key is not 01030103 but 1313
'1' + 13 = 49 + 13 = 62 which is ">" symbol in Ascii.

But as I said, this is minor issues mainly related to your misunderstanding, not to bug itself.

Now IMPORTANT part : Please make this experiment I tell you.

1. Make file contain 100 000 "1".

2. Use exactly the keys "12131213" to crypt it.

1
2
3
4
        uint64_t key = 12131213;
	uint64_t key2 = 12131213;
	uint64_t key3 = 12131213;
	uint64_t key4 = 12131213;


3. Send and Recv crypt message via Socket several times until you get a bug during uncrypt.

4. Show me result from shifting keys problem.

I expected something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <vector>
#include <string>
using namespace std;
std::string uncrypt(const uint64_t& key, const uint64_t& key2, const uint64_t& key3, const uint64_t& key4, std::string msg) {
	std::string tk(to_string(key) + to_string(key2) + to_string(key3) + to_string(key4)); //text key
	vector<int> tmp_tk;
	if (tk.size() % 2 != 0) tk += tk[0];
	while (tk.size() > 0) {
		tmp_tk.push_back(atoi(tk.substr(0, 2).c_str()));
		tk = tk.substr(2);
	}
	for (int i(0); i < tmp_tk.size(); ++i) tk += (char)tmp_tk[i];
	while (tk.size() < msg.size()) {
		tk += tk;
	}

	if (msg.size() <= tk.size()) {
		std::string tmp = "";
		for (int i(0); i < msg.size(); ++i) {
			char tmp_val = msg[i] - tk[i];
			if (tmp_val < -127) tmp_val += 255;
			tmp += tmp_val;
		}
		return tmp;
	}
}

std::string crypt(const uint64_t& key, const uint64_t& key2, const uint64_t& key3, const uint64_t& key4, std::string msg) {
	std::string tk(to_string(key) + to_string(key2) + to_string(key3) + to_string(key4)); //text key
	vector<int> tmp_tk;
	if (tk.size() % 2 != 0) tk += tk[0];
	while (tk.size() > 0) {
		tmp_tk.push_back(atoi(tk.substr(0, 2).c_str()));
		tk = tk.substr(2);
	}
	for (int i(0); i < tmp_tk.size(); ++i) tk += (char)tmp_tk[i];
	while (tk.size() < msg.size()) {
		tk += tk;
	}

	if (msg.size() <= tk.size()) {
		std::string tmp = "";
		for (int i(0); i < msg.size(); ++i) {
			char tmp_val = msg[i] + tk[i];
			//if (tmp_val < -127) tmp_val += 255;
			tmp += tmp_val;
		}
		return tmp;
	}
}
int main()
{
	std::string msgO{ "1111111111111111111111111111111111111" };
	uint64_t key = 12131213;
	uint64_t key2 = 12131213;
	uint64_t key3 = 12131213;
	uint64_t key4 = 12131213;
	std::string msgC{ crypt(key, key2, key3, key4, msgO) };
	std::string msgU{ uncrypt(key, key2, key3, key4, msgC) };
	std::string msgInsert{ "0" };

	cout << "Original Message: "<< msgO << endl;
	cout << "Crypt Message: " << msgC << endl;
	cout << "Ucrypt Message: " << msgU << endl << endl;

	cout << "But now we will insert two '0's inside Crypt message... " << endl;
	cout << msgC << endl;
	cout << "...simulating send-recv parasites '0's adding." << endl << endl;
	
	cout << "So our destored Crypt Message become:" << endl;
	msgC.insert(10, msgInsert);
	msgC.insert(27, msgInsert);
	cout << msgC << endl << endl;

	cout << "When we try to uncrypt this distored message, result will be: " << endl;
	cout << uncrypt(key, key2, key3, key4, msgC) << endl;
}



Original Message: 1111111111111111111111111111111111111
Crypt Message: =>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=
Ucrypt Message: 1111111111111111111111111111111111111

But now we will insert two '0's inside Crypt message...
=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=>=
...simulating send-recv parasites '0's adding.

So our destored Crypt Message become:
=>=>=>=>=>0=>=>=>=>=>=>=>=>0=>=>=>=>=>=

When we try to uncrypt this distored message, result will be:
1111111111$0202020202020202#11111111111


Do you see how result alternate? If problem is shifting it will show it clearly.

P.s. And Zaap, you must organize your brain little bit. Usually many programmers when they have any problems, they start to chaotically move in their code, to change that and that, hoping to catch the problem accidentally. In this way, they begin to change the conditions in which the problem occurs and often make the situation even more complicated. Think of bugs as knots. If you just try to untie some tangled rope without thinking about your strategy first, it will get tangled even more. So stop to change chaotically code lines, please, and do what I tell you. This your bug, I can catch and deal with it under 1 hour if I have the right conditions - you make it hard, 3 days problem - doing what you want. I know it's a matter of honor to catch it yourself - but FUCK the BUG, I rather want to teach you how to think when you have such problems in future. So do what I want, and you will see how easy things will become.
Last edited on
Pages: 1234