| 
			
				|  | Cheat Engine The Official Site of Cheat Engine
 
 
 |  
 
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| Polynomial Grandmaster Cheater
 
 ![]() Reputation: 5 
 Joined: 17 Feb 2008
 Posts: 524
 Location: Inside the Intel CET shadow stack
 
 | 
			
				|  Posted: Thu Sep 18, 2008 6:42 am    Post subject: Break my crypto |   |  
				| 
 |  
				| I wrote an encryption class a while back that uses some simple operations and feedback techniques to encrypt data quickly and relatively securely. I called it SimpleCrypt and I've been using it in applications for quite a while now. 
 Here's the encrypt/decrypt routines:
 
 VB.NET:
 
  	  | Code: |  	  | Public Function Encrypt(ByVal data() As Byte, ByVal keydata() As Byte) As Byte() Dim key() As Byte = SHA256.Create().ComputeHash(keydata)
 Dim retData(data.Length - 1) As Byte
 For i As Integer = 0 To data.Length - 1
 retData(i) = data(i) Xor key(i Mod (key.Length - 1))
 retData(i) = retData(i) Xor (i Mod 255)
 If i > 0 Then
 retData(i) = retData(i) Xor data(i - 1)
 End If
 If i Mod 2 = 0 Then
 retData(i) = 255 - retData(i)
 End If
 Next
 Return retData
 End Function
 
 Public Function Decrypt(ByVal data() As Byte, ByVal keydata() As Byte) As Byte()
 Dim key() As Byte = SHA256.Create().ComputeHash(keydata)
 Dim retData() As Byte = data
 For i As Integer = 0 To data.Length - 1
 If i Mod 2 = 0 Then
 retData(i) = 255 - retData(i)
 End If
 If i > 0 Then
 retData(i) = retData(i) Xor data(i - 1)
 End If
 retData(i) = retData(i) Xor (i Mod 255)
 retData(i) = data(i) Xor key(i Mod (key.Length - 1))
 Next
 Return retData
 End Function
 | 
 
 And in C# (excuse any errors - I wrote this in Notepad and I've not used C# in a while)
 
  	  | Code: |  	  | public byte[] Encrypt(byte data[], byte keydata[]) {
 byte key[] = SHA256.Create().ComputeHash(keydata);
 byte retData[data.Length - 1];
 for(int i = 0; i < data.Length; i++)
 {
 retData[i] = data[i] ^ key[i % (key.Length - 1)];
 retData[i] = retData[i] ^ (i % 255);
 if(i > 0)
 {
 retData[i] = retData[i] ^ data[i - 1];
 }
 if(i % 2 == 0)
 {
 retData[i] = 255 - retData[i];
 }
 }
 return retData;
 }
 
 public byte[] Decrypt(byte data[], byte keydata[])
 {
 byte key[] = SHA256.Create().ComputeHash(keydata);
 byte retData[] = data;
 for(int i = 0; i < data.Length; i++)
 {
 if(i % 2 == 0)
 {
 retData[i] = 255 - retData[i];
 }
 if(i > 0)
 {
 retData[i] = retData[i] ^ data[i - 1];
 }
 retData[i] = retData[i] ^ (i % 255);
 retData[i] = data[i] ^ key[i % (key.Length - 1)];
 }
 return retData;
 }
 | 
 
 I've encoded an executable file with my algorithm, and it's your job to try to decrypt it
   
 Some hints:
 1) Don't try to bruteforce. The idea of breaking an algorithm is to find a way to defeat it without just bruteforcing. Besides, I've used a key that'll take you a long time to break.
 2) The original executable is a .NET PE, so you know some information about what some of the bytes were (MZ header, DOS execution message, etc).
 3) Pay close attention to the i > 0 clause.
 4) The algorithm does not add or remove any bytes - original data length is equal to the encrypted data length.
 5) The key is hashed to 256 bits (32 bytes) and the file is larger than 32 bytes. Repetition is important!
 
 Enjoy
   
 Update - 6th October 2008
 I've updated the code to use Rijndael's S-Box and a custom function-box for increased security. I realised that the algebraic simplicity of the algorithm caused problems as there was no confusion employed, so the S-Box should help to fix that. The function box also helps increase security by adding a large amount of "unknown processing" to the algorithm - the operations done on each byte are different depending on the key. I've also turned the algorithm into a 4-round version that uses a different key for each round.
 
 Note that I haven't modified the challenge, so the attached file on the original post is still using the old version.
 
 I've attached the source code (simplecrypt2_source.zip) for VB.NET and C#, which you may use and distribute in accordance with the notice in the source.
 
 Last edited by Polynomial on Sun Oct 05, 2008 6:16 pm; edited 1 time in total
 |  |  
		| Back to top |  |  
		|  |  
		| rapion124 Grandmaster Cheater Supreme
 
 ![]() Reputation: 0 
 Joined: 25 Mar 2007
 Posts: 1095
 
 
 | 
			
				|  Posted: Tue Sep 23, 2008 7:18 pm    Post subject: |   |  
				| 
 |  
				| This isn't really your own cryptographic algorithm, considering you used a 256 bit SHA hash. If the hash wasn't there, it would be very easy. |  |  
		| Back to top |  |  
		|  |  
		| Polynomial Grandmaster Cheater
 
 ![]() Reputation: 5 
 Joined: 17 Feb 2008
 Posts: 524
 Location: Inside the Intel CET shadow stack
 
 | 
			
				|  Posted: Tue Sep 23, 2008 8:09 pm    Post subject: |   |  
				| 
 |  
				| That is not true. If the hash algorithm was not in use I could set a random 256-bit key myself. 
 For example, here's a random 256-bit key I created in notepad:
 
  	  | Code: |  	  | 5, 19, 54, 197, 0, 28, 98, 181, 120, 55, 19, 33, 49, 30, 148, 107, 99, 114, 216, 95, 255, 126, 97, 4, 126, 63, 196, 103, 100, 207, 201, 253 | 
 
 Just as secure
   
 In fact I could take a UTF8 string of 250 characters and use it as a key if I really wanted.
 
 The hash algorithm is there because short passwords break this kind of cryptography. The cryptographic algorithm is my own, the key generation algorithm is not, but I could equally have used a PRNG to generate a 256-bit key so the point is moot.
 |  |  
		| Back to top |  |  
		|  |  
		| pkedpker Master Cheater
 
 ![]() Reputation: 1 
 Joined: 11 Oct 2006
 Posts: 412
 
 
 | 
			
				|  Posted: Tue Sep 23, 2008 11:30 pm    Post subject: |   |  
				| 
 |  
				| looks very similar to world of warcraft packet encryption. Close but not exactly.. 
 
  	  | Code: |  	  | void WowCrypt::EncryptSend(uint8 *data, size_t len)
 {
 if (!_initialized) return;
 if (len < CRYPTED_SEND_LEN) return;
 
 for (size_t t = 0; t < CRYPTED_SEND_LEN; t++) {
 _send_i %= _key.size();
 data[t] = _send_j = (data[t] ^ _key[_send_i]) + _send_j;
 ++_send_i;
 }
 }
 
 void WowCrypt::DecryptRecv(uint8 *data, size_t len)
 {
 if (!_initialized) return;
 if (len < CRYPTED_RECV_LEN) return;
 uint8 x;
 
 for (size_t t = 0; t < CRYPTED_RECV_LEN; t++) {
 _recv_i %= _key.size();
 x = (data[t] - _recv_j) ^ _key[_recv_i];
 ++_recv_i;
 _recv_j = data[t];
 data[t] = x;
 }
 }
 
 | 
 _________________
 
 |  |  
		| Back to top |  |  
		|  |  
		| Polynomial Grandmaster Cheater
 
 ![]() Reputation: 5 
 Joined: 17 Feb 2008
 Posts: 524
 Location: Inside the Intel CET shadow stack
 
 | 
			
				|  Posted: Wed Sep 24, 2008 4:05 am    Post subject: |   |  
				| 
 |  
				| I'm really surprised at that... I've never looked at WoW's protocols (I don't play it and I hate it) so it's a case of unassociated discovery - two people in two different locations that have never met each other and are unaware of each other's existence both developing the same invention or theory. 
 In fact this is quite a confidence boost - if what I developed on my own is similar to something a multi-million dollar games development corporation came up with, I must be doing something right!
 |  |  
		| Back to top |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 You cannot attach files in this forum
 You cannot download files in this forum
 
 |  |