2019-03-24 02:14:30 (edited by amerikranian 2019-03-24 02:51:19)

So obviously I'm missing something here.
pickle is used for seriolization, but it's incredibly easy to revirce. All you have to do is open my file and try multiple types of variables till you find one that works and you've got what I saved.
Pycrypto gives me an error that my visual studio is missing a left brace before some file (I've tried uninstalling, repairing, reinstalling, nothing).
Cryptography can't encrypt dictionaries, which is what I'd like to save and then restore.
So how are you supposed to encrypt a simple save file? No amount of searching brought me to that answer. Do I really have to build an encrypter on my own? While yes, people can do that, you'd also figure that somebody would already have done it by now. How are you supposed to encrypt anything? I realize that encryption is a more difficult topic to give help on (seeming as if you give advice you have to play nice, also known as if you suggest a method you can break it), but I'm truly stuck.
And people wonder why the beginners choose bgt...

2019-03-24 04:31:38

Do you have to build an encryptor on your own? No, obviously. Even people with very good knowledge in security will make a flawed encryptor.

Here is a link to a guide for encryption in python. It doesn't explain how it works, just how to do it. pycrypto is in there, but they show various libs other than that: https://docs.python-guide.org/scenarios/crypto/

Now I'll give you some explanation. Pickle is just a serializer, it doesn't encrypt, its only job is to save an object and its state. You throw an object at pickle, pickle burps back serialized data and you can do whatever you want with it. You can store it to a file or send it over the wire to a server or another client or a remote database or what not. Now anyone can take serialized data and deserialize it, meaning it will convert back to its original object state, usable in your code. It's not safe, it's a convenient way to persist data.

Encryption is the process of blurring data so that it's impossible to make sense of it. You can very well encrypt serialized data, you can encrypt any data whatsoever. However, here's what you need to know. You encrypt data with a key. In symetric encryption, the key used to encrypt is the exact same key you need to decrypt. In asymetric encryption, you use a different key to encrypt and decrypt. The key to encrypt is public, meaning anyone can see it and the key to decrypt is private, meaning it must be safely stored somewhere. This means that anyone can encrypt data with that key, but only the holder of the private key will be able to read that data.

Now, if you make a local game, meaning that the game will run on the player's computer and that there is no server, you don't care about asymetric encryption, because there is no purpose of it. You will want to use symetric encryption, but there is something super important you must know. You cannot safely store that key. This means that no matter what you do, someone clever will be able to read that local file by decrypting it. What they have to do is find the key you used to encrypt it and if your game running locally on the PC can decrypt the file, it means it must have the key and if the local program has the key, then it is possible for someone to intercept it.

That being said, it can make someone's life harder, because retreiving that key can be difficult depending on how you do it. And you get to the difficult part of cryptography, which is key management. The problem is not the encryption algorithm, we have really good and safe algorithms, the problem is to securely manage, use, store, transfer that key.

As soon as the key touches something you don't control, consider that key compromised, it's not safe to use it. Again, I wanna stress this, if you make a local game running on a local PC and the program can decrypt the files, your key will always be considered compromised, there is nothing you can do about it.

A good symetric algorithm for encryption is AES-256, though you can also use AES-128. Block cyphers like AES have multiple modes of encryption, I suggest CBC with IV or CTR. An IV is an initialization vector, it must be random every time you encrypt data, but it's not a secret. I can tell the whole world I encrypted this message using this IV, it's totally safe as long as they don't have the key. You can use the same key to encrypt multiple times, but just take for granted that the more you use a key, the less safe it is. Changing a key is called key rotation and is probably not necessary in your case.

Reading is one form of escape. Running for your life is another. ― Lemony Snicket

2019-03-24 09:42:03 (edited by Ethin 2019-03-24 09:43:26)

@Origine, very good post on cryptography. 'd recommend GCM mode for AES encryption, IMO. (You could also use ChaCha20+Poly1305, which is AES in GCM mode without all the hardware acceleration and CPU-specific instructions and possible fallbacks to slower software implementations). It doesn't add any (outward/programmer-facing) complexity, but it is majorly different from CBC or CTR mode. CBC mode works by taking the current block of data (called the "plaintext") and XORing that block of data either with the previous block of data, or with the initialization vector (IV), then sending the result of that operation through the cipher, which outputs a new block of encrypted data (called the "ciphertext"). GCM works on a hole different level though. When GCM mode is used, it maintains an internal counter value. When you go to encrypt data, the value of that counter is passed through the cipher, and the result of encrypting the value of that counter is XORed with the plaintext, creating the ciphertext. So, the major differences are that CBC encrypts the plaintext with data that is already known before the operation even occurs(the initialization vector or prior block of data); GCM mode XORs the plaintext with output created by the block cipher, making it very difficult (if not impossible) for anyone to guess the output unless that person knows both the ciphertext and plaintext beforehand.
There are other things that make GCM and CBC different, as GCM provides both privacy and integrity and CBC doesn't, but that's not relevant to this discussion.
I digress, however. origine is right; if your performing encryption and decryption locally (which is most likely the wisest thing to do, as doing it remotely can cause massive delays depending on the speed of the connection) your key is compromised. Not immediately, but it will be eventually. There are ways to mitigate the discovery of the key via simple or even complex methods, such as well-written, secure memory management and storage routines, but eventually someone will obtain your key, even if you do everything correctly. It may not even be something you did; it could be a bug in the operating system, a processor bug (i.e. meltdown/spectre), a bug in the implementation of the algorithm you choose to use, and so on. So you can't prevent someone from getting your key, but you can make it pretty damn hard to do. Hope I didn't confuse anyone! smile
Just saw your question. One way you could encrypt a dictionary (or any type) is to serialize it, as Origine recommended, then encrypt that serialized data and do with it what you will.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2019-03-24 10:17:48

Yeah I wanted to talk about good practices in cryptography and how it works. I'm curious, what do you want to achieve with cryptography or what do you want to prevent with it in your particular case, OP?

@Ethan, doing encryption / decryption remotely would indeed secure the key, but it would serve no purpose. The question is against who are we trying to secure the information? If that person is the user / player, then decrypting remotely would probably make it even easier to see the decrypted information, if it's sent over HTTPS, then just open Fiddler or any web proxy and intercept it. It would require one additional layer of encryption in the application layer which is not required.

Reading is one form of escape. Running for your life is another. ― Lemony Snicket

2019-03-24 11:10:12

@4, that's why I said that performing cryptographic ops locally is a wiser idea than sending data like that over the internet. The key will always be visible, no matter what you do; its looking at the key that's hard. So the key is transparent, hard to see, and making it opaque is the hard part.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2019-03-24 15:38:55 (edited by amerikranian 2019-03-24 15:39:20)

@4, I am trying to get a program to store stats. I have a small thingy built, now I just want it's stats to be stored in such a way so that the user can't edit it.
The second post was also helpful. Thank you.