🔒 Locked
Encryption
Advertisement
Original Post
I want all of my maps and other misc. data in my game to not be easily accessable by the end user. I decided to encrypt the files and unencrypt them when accessing the data. My functions look like this:
#include
#include
#include
#define ENCRYPT_LEVEL 16
void encrypt(char* string)
{
for (int i=0; i = string[i] + ENCRYPT_LEVEL;
}
void unencrypt(char* string)
{
for (int i=0; i
XOR encryption is a better encryption than simply adding a number and then subtracting it. Take a 32 bit number or so, and then XOR everything by it. To decrypt, you just XOR is by the same number. Works every time.
PS. Whenever you put an i between two brackets the forum software interprets that as italics. For example, if I put this is all in italics . However, if I put [ i ]This is not in italics[ /i ]. Just thought you might want to use index instead of i.
------------------------------
#pragma twice
PS. Whenever you put an i between two brackets the forum software interprets that as italics. For example, if I put this is all in italics . However, if I put [ i ]This is not in italics[ /i ]. Just thought you might want to use index instead of i.
------------------------------
#pragma twice
sharewaregames.20m.com
Edited by - furby100 on October 12, 2000 12:37:58 PM
Even just XOR''ing your entire data set isn''t very secure if you''re using only a single value. Try doing some operation on your encryption key after every operation, to keep it changing. For example, say ENCRYPT_LEVEL is an int instead of a #define, then you could insert ENCRYPT_LEVEL *= 119; or such at the bottom of your loop.
I got one of those CueCats from Radio Shack because it''s free and I wrote a program to decode the output. My program''s in VB and does exactly what your trying to do kinda.
ConvBinary is the XORed byte that is used on every character in the string. If you wanted you could have as many bytes as you wanted.
NumDots is just a variable to check to see if it''s a valid input from the CueCat which uses periods to seperate fields.
TempBinary is the CueCat''s text converted to 6bits per character (Base 64) and mushed together and then XORed by the 8bit key.
Base64$() is the 64 character array that is used by the CueCat.
Hope this helps. For my game I just convert everything to base 256 and compress. How everything is stored is also somewhat random. If the file gets one byte off it won''t load correctly. I just cram everything together with no seperator and in binary format.
Ben
ConvBinary is the XORed byte that is used on every character in the string. If you wanted you could have as many bytes as you wanted.
NumDots is just a variable to check to see if it''s a valid input from the CueCat which uses periods to seperate fields.
TempBinary is the CueCat''s text converted to 6bits per character (Base 64) and mushed together and then XORed by the 8bit key.
Base64$() is the 64 character array that is used by the CueCat.
Hope this helps. For my game I just convert everything to base 256 and compress. How everything is stored is also somewhat random. If the file gets one byte off it won''t load correctly. I just cram everything together with no seperator and in binary format.
Ben
|
You don''t want to get too caught up in trying to defeat hackers. Everything you can do they can undo. You make it impossible for them to figure out how the file is encoded so they disassemble your program. All you want to do is discourage the casual hacker. The more you put into stopping a hacker the less time you have to make a good game. The fundamental truth is that as long as your program runs on their computer you have no control over it. No matter how difficult it is to hack a program someone will do it and when they do they will give their hard gained knowledge to anyone that wants it. Diablo I on battle.net wasn''t destroyed by thousands of highly skilled hackers. It was destroyed by thousands of people that knew little more than how to run a program.
XOR encryption looks too easy. If it''s easy to do, it''s easy to break.
Using a one-time pad cypher, you can be sure that your stuff will be completely secure, but it would not work for your scale, or the repetitive nature of your data. Forget what I said about one-time pad cyphers.
You could use a nearly unbreakable cypher, though. Check out this grid:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
HIJKLMNOPQRSTUVWXYZABCDEFG
IJKLMNOPQRSTUVWXYZABCDEFGH
JKLMNOPQRSTUVWXYZABCDEFGHI
KLMNOPQRSTUVWXYZABCDEFGHIJ
LMNOPQRSTUVWXYZABCDEFGHIJK
MNOPQRSTUVWXYZABCDEFGHIJKL
NOPQRSTUVWXYZABCDEFGHIJKLM
OPQRSTUVWXYZABCDEFGHIJKLMN
PQRSTUVWXYZABCDEFGHIJKLMNO
QRSTUVWXYZABCDEFGHIJKLMNOP
RSTUVWXYZABCDEFGHIJKLMNOPQ
STUVWXYZABCDEFGHIJKLMNOPQR
TUVWXYZABCDEFGHIJKLMNOPQRS
UVWXYZABCDEFGHIJKLMNOPQRST
VWXYZABCDEFGHIJKLMNOPQRSTU
WXYZABCDEFGHIJKLMNOPQRSTUV
XYZABCDEFGHIJKLMNOPQRSTUVW
YZABCDEFGHIJKLMNOPQRSTUVWX
ZABCDEFGHIJKLMNOPQRSTUVWXY
now, you have to come up with a key, the longer the better, the less repetitive the better. If you use the top row and the left-most collum like number lines and use the letters like a coordinate system, then using the first character in you key and the first character in you data, you can track across to the point where they cross and get the encrypted letter. Check out this example:
DATA: hello how are you
KEY: iamgoodhowareyou
the first letter in the data is ''h'', the first letter in the key is ''i''. Track h across the top and i down the side, where the two cross is the new letter, P. I''ll skip ahead and do the rest
PEXRC KVK AGI MIC
Since the last letter in the data did not have a key letter associated with it I started back at the beginning of the key.
Notice certain things about the encrypted data. The two ''l''s in hello are encrypted differently (X and R) while the ''h'' and ''w'' in how are encrypted the same (K) this makes an almost completely random code. Now, if you use a random string for the key, and apply it to non-readable data (machine-code, map data, whatever), then you will get something that is virtually unbreakable. The thing about this code is that depending on what the key is, it could mean something completely different, especially if the key is random.
There is only one way to break the code. You hope that the key is not random, and you hope that the encrypted data is a rather long passage of text. then, you guess that certain words are the word ''the'', then you work out a partial key. If you come up with a key that makes sense (a word perhaps) then you know your on the right track. You continue in this manner until you get the entire key, or enough of it that you can guess the rest. But this is only if the key was a phrase and the data was readable text.
You can add any character you want to this, then reference it easily, especially with a C/C++ program:
and that should be it!
Using a one-time pad cypher, you can be sure that your stuff will be completely secure, but it would not work for your scale, or the repetitive nature of your data. Forget what I said about one-time pad cyphers.
You could use a nearly unbreakable cypher, though. Check out this grid:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
HIJKLMNOPQRSTUVWXYZABCDEFG
IJKLMNOPQRSTUVWXYZABCDEFGH
JKLMNOPQRSTUVWXYZABCDEFGHI
KLMNOPQRSTUVWXYZABCDEFGHIJ
LMNOPQRSTUVWXYZABCDEFGHIJK
MNOPQRSTUVWXYZABCDEFGHIJKL
NOPQRSTUVWXYZABCDEFGHIJKLM
OPQRSTUVWXYZABCDEFGHIJKLMN
PQRSTUVWXYZABCDEFGHIJKLMNO
QRSTUVWXYZABCDEFGHIJKLMNOP
RSTUVWXYZABCDEFGHIJKLMNOPQ
STUVWXYZABCDEFGHIJKLMNOPQR
TUVWXYZABCDEFGHIJKLMNOPQRS
UVWXYZABCDEFGHIJKLMNOPQRST
VWXYZABCDEFGHIJKLMNOPQRSTU
WXYZABCDEFGHIJKLMNOPQRSTUV
XYZABCDEFGHIJKLMNOPQRSTUVW
YZABCDEFGHIJKLMNOPQRSTUVWX
ZABCDEFGHIJKLMNOPQRSTUVWXY
now, you have to come up with a key, the longer the better, the less repetitive the better. If you use the top row and the left-most collum like number lines and use the letters like a coordinate system, then using the first character in you key and the first character in you data, you can track across to the point where they cross and get the encrypted letter. Check out this example:
DATA: hello how are you
KEY: iamgoodhowareyou
the first letter in the data is ''h'', the first letter in the key is ''i''. Track h across the top and i down the side, where the two cross is the new letter, P. I''ll skip ahead and do the rest
PEXRC KVK AGI MIC
Since the last letter in the data did not have a key letter associated with it I started back at the beginning of the key.
Notice certain things about the encrypted data. The two ''l''s in hello are encrypted differently (X and R) while the ''h'' and ''w'' in how are encrypted the same (K) this makes an almost completely random code. Now, if you use a random string for the key, and apply it to non-readable data (machine-code, map data, whatever), then you will get something that is virtually unbreakable. The thing about this code is that depending on what the key is, it could mean something completely different, especially if the key is random.
There is only one way to break the code. You hope that the key is not random, and you hope that the encrypted data is a rather long passage of text. then, you guess that certain words are the word ''the'', then you work out a partial key. If you come up with a key that makes sense (a word perhaps) then you know your on the right track. You continue in this manner until you get the entire key, or enough of it that you can guess the rest. But this is only if the key was a phrase and the data was readable text.
You can add any character you want to this, then reference it easily, especially with a C/C++ program:
|
and that should be it!
One of the basic rules of safe encryption:
Always assume that the person trying to hack your data knows the algorithm you used to encrypt it.
Note that this does NOT mean that the hacker will be able to see your data - he/she will not have the key, and the difficulty should be in figuring out what the key is.
People might not remember what you said, or what you did, but they will always remember how you made them feel.
~ (V)^|) |<é!t|-| ~
Always assume that the person trying to hack your data knows the algorithm you used to encrypt it.
Note that this does NOT mean that the hacker will be able to see your data - he/she will not have the key, and the difficulty should be in figuring out what the key is.
People might not remember what you said, or what you did, but they will always remember how you made them feel.
~ (V)^|) |<é!t|-| ~
Finding the key isn't that hard. After all, the program itself has to have access to the key in order to run. Therefore, the hacker runs the program, and tries to find the key while the program is running. He/she finds all of the locations that the decryption algorithm accesses while running. One of those locations has to be the key. That easily defeats capn_midnight's code. There are tools for scanning memory locations while a program is running.
I agree with Wizer. Keep the casual hacker out, but don't expect to defeat every hacker in the world. It's next to impossible.
Many times, the hacker simply uses your own decryption algorithm to access the files -- make sure the key isn't in the decryption algorithm itself.
capn_midnight also made another no-no: He hard-coded the password into the code in plain sight; that's the first place somebody will look. The password should itself be encoded/encrypted.
Here's a good article on the subject: http://www.gamasutra.com/features/20000724/pritchard_01.htm
Edited by - CobraA1 on October 13, 2000 2:25:51 PM
I agree with Wizer. Keep the casual hacker out, but don't expect to defeat every hacker in the world. It's next to impossible.
Many times, the hacker simply uses your own decryption algorithm to access the files -- make sure the key isn't in the decryption algorithm itself.
capn_midnight also made another no-no: He hard-coded the password into the code in plain sight; that's the first place somebody will look. The password should itself be encoded/encrypted.
Here's a good article on the subject: http://www.gamasutra.com/features/20000724/pritchard_01.htm
Edited by - CobraA1 on October 13, 2000 2:25:51 PM
Cobra and Wizer are correct; it is virtually impossible to prevent the breaking of your encryption algorithm. All you can do is make it difficult for the hackers/crackers, but you can''t stop them completely.
While simple encryption and such will stop the casual hacker, it will not discourage the skilled ones. This usually isn''t a problem, unless the skilled ones pass their results (in the form of cracks, cheat programs, etc.) on to the masses, which often happens. If your algorithm and key are available somewhere in your program, they will be able to find it if they work hard enough.
Of course, you can make that a *lot* of work for them. Many people who do this kind of thing rely on tools such as SoftICE and other debuggers/disassemblers. If you''re absolutely diehard about giving these folks a hard time, there are tricks you can pull that can A) make your program virtually impossible to disassemble correctly, B) detect a good number of debuggers and disassemblers, C) *crash* several of these debuggers (such as SoftICE) when detected, D) prevent many of them from working by doing things like attaching your code into kernel32''s address space (where many debuggers will refuse to go), and so forth.
All of these things can be done, and while they will not stop people who insist on deciphering your techniques forever, it can at least delay and annoy them. But many of these tricks are a lot of work, and you must ask yourself how far you really want (or need) to go.
While simple encryption and such will stop the casual hacker, it will not discourage the skilled ones. This usually isn''t a problem, unless the skilled ones pass their results (in the form of cracks, cheat programs, etc.) on to the masses, which often happens. If your algorithm and key are available somewhere in your program, they will be able to find it if they work hard enough.
Of course, you can make that a *lot* of work for them. Many people who do this kind of thing rely on tools such as SoftICE and other debuggers/disassemblers. If you''re absolutely diehard about giving these folks a hard time, there are tricks you can pull that can A) make your program virtually impossible to disassemble correctly, B) detect a good number of debuggers and disassemblers, C) *crash* several of these debuggers (such as SoftICE) when detected, D) prevent many of them from working by doing things like attaching your code into kernel32''s address space (where many debuggers will refuse to go), and so forth.
All of these things can be done, and while they will not stop people who insist on deciphering your techniques forever, it can at least delay and annoy them. But many of these tricks are a lot of work, and you must ask yourself how far you really want (or need) to go.
Here''s another idea. I think you have to hit Ctrl-D to fire up SoftIce while another prog is running. It may be possible to "filter" the keyboard and if they hit this key combination then just disregard it and through it out in the trash.
"We are the music makers, and the dreamers of the dreams."
- Willy Wonka
"We are the music makers, and the dreamers of the dreams."
- Willy Wonka
I believe SoftICE traps the keyboard at a lower level than the application (possibly through a VxD or whatnot), so you may not be able to filter it. However, you can detect and remove SoftICE''s presence via other means (although they''re not trivial to implement).
"If someone can make it, someone else can unmake it" - quote (or some variation thereof) from "The Score."
Anyway the point is that it is impossible to make an unbreakable encryption algorithm or key. It may take someone a really unreasonable amount time to break it (as is the case with encryption used for protecting e-commerce) but it can still be done.
In the context of games and not allowing people to tamper with the files, you should just make it hard for the casual hacker to tamper with them.
Anyway the point is that it is impossible to make an unbreakable encryption algorithm or key. It may take someone a really unreasonable amount time to break it (as is the case with encryption used for protecting e-commerce) but it can still be done.
In the context of games and not allowing people to tamper with the files, you should just make it hard for the casual hacker to tamper with them.
You should ask yourself: Why shouldn''t anyone be able to access the files? There are a couple reasons where I could see you not allowing them to tamper with the files, but in most cases you aren''t helping yourself or the user, just being annoying.
BTW: Checksums are probably a better idea than encryption.
[Resist Windows XP''s Invasive Production Activation Technology!]
BTW: Checksums are probably a better idea than encryption.
[Resist Windows XP''s Invasive Production Activation Technology!]
For encryption: If you want good security, then you should use a ''real'' encryption system, such as RC-5 or Blowfish.
Look at: http://cnscenter.future.co.kr/crypto/algorithm/block.html
For debugging: Hard to stop a debugger. Professional reverse engineer experts use hardware debuggers, these are systems that are directly connected to the CPU / Chipset, there is no way of stopping those.
Don''t try to defeat the debugger, try to defeat the hacker''s brain
A very good way is to create a decryption system based on a stack based virtual machine. Self modifying opcodes, procedural branching systems, self decrypting boolean tables and code.
Several years ago, I took part in a hacking contest, the objective was to hack a tiny little DOS programm called ''hackme.com''. It''s size was exactly 4353 bytes. It was written by some russian guy, and used all the techniques described above. It was virtually impossible to hack, at least 200 people tried it. In the end, some totally sick guy, who debugged it for over 48 hours nonstop (!), managed to break it.
Keep in mind that the more you will secure your data, the more people will be tempted to hack it (''What is he hiding with *such* an encryption system ??'').
Null And Void: I don''t think that checksum is a good idea. I think the point is not to prevent tampering, but to prevent ripping of eg. textures. So encryption will be the better choice.
A.H aka Blueshift
Look at: http://cnscenter.future.co.kr/crypto/algorithm/block.html
For debugging: Hard to stop a debugger. Professional reverse engineer experts use hardware debuggers, these are systems that are directly connected to the CPU / Chipset, there is no way of stopping those.
Don''t try to defeat the debugger, try to defeat the hacker''s brain
A very good way is to create a decryption system based on a stack based virtual machine. Self modifying opcodes, procedural branching systems, self decrypting boolean tables and code.
Several years ago, I took part in a hacking contest, the objective was to hack a tiny little DOS programm called ''hackme.com''. It''s size was exactly 4353 bytes. It was written by some russian guy, and used all the techniques described above. It was virtually impossible to hack, at least 200 people tried it. In the end, some totally sick guy, who debugged it for over 48 hours nonstop (!), managed to break it.
Keep in mind that the more you will secure your data, the more people will be tempted to hack it (''What is he hiding with *such* an encryption system ??'').
Null And Void: I don''t think that checksum is a good idea. I think the point is not to prevent tampering, but to prevent ripping of eg. textures. So encryption will be the better choice.
A.H aka Blueshift
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement