Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (798)
Games in Android Showcase (234)
games submitted by our members
Games in WIP (865)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Java Cryptography  (Read 7777 times)
0 Members and 1 Guest are viewing this topic.
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Posted 2014-12-15 22:15:03 »

Since my current encryption method wont work, I looked into the Java cryptography class. I found a decent example (http://www.java2s.com/Code/Java/Security/EncryptionanddecryptionwithAESECBPKCS7Padding.htm), but there were no tutorials I could find that could explain this simply. What I plan on doing is encrypting the player file so it can't be changed (prevent cheaters). Any good tutorials or explanations?
Offline Gibbo3771

JGO Kernel


Medals: 128
Projects: 5
Exp: 1 year


Currently inactive on forums :(


« Reply #1 - Posted 2014-12-15 22:24:54 »

Do you have a game that players can cheat in?

If it is for android don't bother, 90% of people can't even navigate to those files.

However, for a nice "simple" encryption that would throw off some kid and/or non tech savvy elderly, use base64.

"This code works flawlessly first time and exactly how I wanted it"
Said no programmer ever
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #2 - Posted 2014-12-15 22:32:34 »

Do you have a game that players can cheat in?

Yes, if they get into the easy to acess save file. if they change any numbers they can change their health and such.

However, for a nice "simple" encryption that would throw off some kid and/or non tech savvy elderly, use base64.

Did some research on Base64, I want it to block out tech savy people. I'm not talking about extreme hackers.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline The Lion King
« Reply #3 - Posted 2014-12-15 22:37:00 »

Can you talk me through your protocol. If you encrypt your player file I am assuming you will need to unencrypt it somehow. How will you do that. Where will your key be, how will you get it.

If your protocol doesn't make any sense then there is no point in doing any encryption.

"You have to want it more than you want to breath, then you will be successful"
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #4 - Posted 2014-12-15 22:39:36 »

What I'll do is encrypt it whenever the player saves or makes a new profile. Whenever my program needs to acess it, It will decrypt it and gather data, leaving the file  encrypted to anyone who looks at it.
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #5 - Posted 2014-12-15 22:42:42 »

But since they have your program, they can easily decompile it and have the key. No dice.
Offline The Lion King
« Reply #6 - Posted 2014-12-15 22:43:55 »

You are missing a crucial point. You have a private key to de-encrypt. How will you get this key and store it in a way that no one else with bad intentions can get it.

If I was trying to hack your program i would notice that, it was opening a file (the key) and using it to unencrypt the file, then later using a key to re-encrypt the file again. I would then find this key and use it to unencrypt the file and do what I want.

I suggest you ignore this fact and just XOR the file with a key hidden in a strange place, to encrypt and un-encrypt your file. It is good enough.

"You have to want it more than you want to breath, then you will be successful"
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #7 - Posted 2014-12-15 22:48:46 »

Or just base-whatever + gzip the save file and put it in a weird place with no file extension and you will have foiled 99+% of would-be hackers. If you're deploying to windows, make that effectively 100%
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #8 - Posted 2014-12-15 23:01:17 »

@The Lion King How do I use XOR? I followed a c++ tutorial on it but couldnt figure out how to conver this to java.
1  
         encrypted += original[i] + (int(key)) + i  % 20; 


@BurntPizza I use JFileChooser so they would know where the file is anyway. But I guess Base64 could do the job.
Offline Slyth2727
« Reply #9 - Posted 2014-12-15 23:27:21 »

@The Lion King How do I use XOR? I followed a c++ tutorial on it but couldnt figure out how to conver this to java.
1  
2  
         
encrypted += original[i] + (int(key)) + i  % 20;


@BurntPizza I use JFileChooser so they would know where the file is anyway. But I guess Base64 could do the job.

No offense but I loled. Use Google every once and a while.

I'll explain the basics before you start searching so you have the gist. I'm assuming you understand bit manipulation basics.
I wrote a little XOR encryption class in C++ at work, I'll see if I remember to bring it back tomorrow afternoon after school and work.
So basically you have a key (which should be an 8 bit binary string like 01000001) with which you XOR each bit of the target string with. So if I had the binary string "01001000 01100101 01101100 01101100 01101111" I would XOR each char with my key (01000001). My result would be something like this:

1  
2  
3  
4  
   01001000 01100101 01101100 01101100 01101111
^  01000001 01000001 01000001 01000001 01000001
-----------------------------------------------
   00001001 00100100 00101101 00101101 00101110


At least that is how I remember it. It was a while ago. Google around some, I could be completely wrong.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #10 - Posted 2014-12-16 02:02:18 »

Thanks, I did some research and learned about all the different bitwise operators. I have an XOR program as well as a binary converter now.
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  
private static final Charset UTF_8 = Charset.forName("UTF-8");
   
   public static void main(String[] args) {
     
      String binary1 = "0011111111101111111111111100101101111100110000001011111000010100";
      String binary2 = "0011111111100000110011001100110011001100110011001100110011001100";

      StringBuilder sb = new StringBuilder();

      for(int i = 0; i < binary1.length(); i++)
          sb.append((binary1.charAt(i) ^ binary2.charAt(i)));

      String result = sb.toString();
      System.out.println(result);
     
     
      String a = "hello";
      String b = "goodbye";
      toBinary(a);
      toBinary(b);
     
     
   }
   
   public static void toBinary(String text) {
        byte[] bytes = text.getBytes();
        StringBuilder binary = new StringBuilder();
        for (byte b : bytes)
        {
           int val = b;
           for (int i = 0; i < 8; i++)
           {
              binary.append((val & 128) == 0 ? 0 : 1);
              val <<= 1;
           }
           binary.append(' ');
        }
        System.out.println("'" + text + "' to binary: " + binary);
   }
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #11 - Posted 2014-12-16 02:06:07 »

Note that you are not XORing the numbers, but instead the ASCII char values.

Think about using a BitSet.
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #12 - Posted 2014-12-16 02:38:29 »

Which numbers are you talking about? The binary numbers? And I don't get how they turn into ASCII cchar values  Huh
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #13 - Posted 2014-12-16 02:53:32 »

Except those aren't binary numbers, they're Strings. (Well everything is numbers in memory when you get down to it, but they aren't the numbers you think they are)

charAt() returns a char, which is a number from this table: http://www.asciitable.com/ (technically it's Unicode, but the first 128 Unicode chars are identical to the ASCII standard)


Think about it. In the mean time here's a simple BitSet impl:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
BitSet key = BitSet.valueOf(new byte[] { 124, 56, 37, -77 });
BitSet data = BitSet.valueOf("Hello World".getBytes());

System.out.println(new String(data.toByteArray()));

xorWithKey(data, key);
System.out.println(new String(data.toByteArray()));

xorWithKey(data, key);
System.out.println(new String(data.toByteArray()));

// xor's data with key
private static void xorWithKey(BitSet data, BitSet key) {
    for (int i = 0; i < data.length(); i++) {
        data.set(i, key.get(i % key.length()) ^ data.get(i));
    }
}


Quote
Hello World
4]I�r�TA
Hello World

Unfortunately, BitSet.xor() doesn't cycle the shorter of two sets, so unless your key is the same number of bits as the data to be encoded, you have to use that helper function. Hopefully you get it.

If it's slow then you can extrapolate it to xoring a byte (or more) at a time with raw arrays, but BitSets are easier to understand.

EDIT: hey my forum rank comes in handy here  Pointing
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #14 - Posted 2014-12-16 03:09:20 »

In the first Line of code (the key). Those numbers are supposed to be the ASCII right?
1  
124 = T
1  
56 = .


And the
1  
xoWithKey()
method; I don't think I understand it because you called it twice and got 2 different outputs.
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #15 - Posted 2014-12-16 03:21:27 »

No the key is just a random number. A "binary string," in this case (124 << 24) | (56 << 16) | (37 << 8) | (-77 & 0xFF) -> 2084054451 -> 1111100001110000010010110110011

xorWithKey just sets each bit of the data to that bit xor'd with the appropriate bit of the key, modulo the key length so that it acts like you repeat the key until it's the same length as the data.

Example:
data = 10010100110  (12 bits)
key = 1011              (4 bits)

key is shorter than the data so BitSet.xor() would only change the first 4 bits of data and the rest would be stay unencrypted. Not what you want.
So instead the key needs to be made longer. Simplest way to do that is to just repeat it until it's long enough:
key = 101110111011 (repeated 3 times, 12 bits)

Now xor them together to "encrypt":
10010100110
101110111011
= 111100011101

Which will be your encrypted data, which looks like gibberish when printed as Unicode.

Do it again, but this time on the encrypted data:
111100011101
101110111011
= 10010100110

Which you will notice is identical to the original data. That's how the "XOR encryption" works.

EDIT: here is the wikipedia page on the subject: http://en.wikipedia.org/wiki/XOR_cipher
Offline Slyth2727
« Reply #16 - Posted 2014-12-16 03:26:21 »

Also, you XOR one bit by the whole key (right?)
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #17 - Posted 2014-12-16 03:27:12 »

I don't understand the question.
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #18 - Posted 2014-12-16 03:37:51 »

I understand now.

I'll have to try this tomorrow, but this XOR encryption can decrypt a string that needs to be parsed as an int?

Pseudo Code
1  
2  
3  
4  
String amount = "500";
XOREncrypt(amount);
XORDecrypt(amount);
int amoutParsed = Integer.parseInt(amount);


And the key, since it's random numbers; is there any maximum or minimum to the key length?
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #19 - Posted 2014-12-16 03:45:28 »

Sure. (as a bonus now that you hopefully understand it, here it is with byte arrays)

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
byte[] data = "500".getBytes();
byte[] key = "imsorandom".getBytes();
         
System.out.println(Integer.valueOf(new String(data)));
         
// encrypt
for (int i = 0; i < data.length; i++) {
    data[i] = (byte) (data[i] ^ key[i % key.length]);
}
         
System.out.println(new String(data)); // not going to try and parse gibberish as an integer
         
// decrypt
for (int i = 0; i < data.length; i++) {
    data[i] = (byte) (data[i] ^ key[i % key.length]);
}
         
System.out.println(Integer.valueOf(new String(data)));


Quote
500
\]C
500

And the key, since it's random numbers; is there any maximum or minimum to the key length?

No, but using this method if the key is longer than the data (such as in this example) the excess is unused.
(Although a key length of 0 would break this code, but in theory you might consider it the identity function)
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #20 - Posted 2014-12-16 03:55:49 »

Wonderful. I see why you're the bitwise Duke Grin
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #21 - Posted 2014-12-16 04:00:01 »

I…I don't even see the code. All I see is blonde, brunette, red-head.



(Bonus pun relative to this thread if you know that guy's name....)
Offline Mr.CodeIt

Senior Devvie


Medals: 2
Projects: 1



« Reply #22 - Posted 2014-12-16 17:01:23 »

On that last system print, (if) I don't make a new string like you did in the console I get outputs like
1  
[B@1d0bc85
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #23 - Posted 2014-12-16 17:26:43 »

That's the byte[] being printed.
If you want to see the nubmers, use Arrays.toString(), and if you want to see the string representation, use new String.
Offline saucymeatman
« Reply #24 - Posted 2014-12-19 19:26:38 »

Why is it a problem that players can change their health?

If it is a local game, and has no in-app purchases, then there is no reason to prevent a player from altering the game. "Cheating" is fun, and dont you want people to have fun : ) ?
"Cheating" has such negative connotations, but really the same implications as "Modding".

If the game is online, then the player should not be able to cheat by editing a local file. If the player can cheat by editing data or code on the client's machine, then the data or code should be moved to the server.

I dont think there are many good reasons for this anti-cheat / anti-modding nonsense : (
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (34 views)
2019-09-04 15:33:17

hadezbladez (3979 views)
2018-11-16 13:46:03

hadezbladez (1444 views)
2018-11-16 13:41:33

hadezbladez (3986 views)
2018-11-16 13:35:35

hadezbladez (769 views)
2018-11-16 13:32:03

EgonOlsen (4085 views)
2018-06-10 19:43:48

EgonOlsen (4664 views)
2018-06-10 19:43:44

EgonOlsen (2753 views)
2018-06-10 19:43:20

DesertCoockie (3647 views)
2018-05-13 18:23:11

nelsongames (3849 views)
2018-04-24 18:15:36
Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!