C# : Encryption - Decryption Class that works good in a project.

Hey,

Would anyone here please share a Encryption class in C# that works properly in Unity games?
Thanks in advance.

Maybe http://www.bouncycastle.org/csharp/ ? (I haven’t implemented it in Unity so I can’t say for sure.)

What’s wrong with System.Security.Cryptography? I’m fairly new to crypto but I’ve seen people avoid System.Security and I don’t know why.

1 Like

@Dustin-Horne @hippocoder

Share some love on the topic, boys? lol

1 Like

I agree with Garth Smith, what’s wrong with System.Security.Cryptography?

Unless OP is looking to do something very specific that System.Security.Cryptography doesn’t support (maybe an algorithm that the old mono framework we use doesn’t support).

But seeing as OP really just said “share a Encryption class”, with no context of requirements… what more could be said on the matter? There’s an entire namespace of classes useful for encryption… question answered.

1 Like

Well, it depends on what you’re wanting to do. If it’s hash computation via HMAC then you might have some issues as the version of .NET (Mono) that Unity uses has a bug that results in an inconsistent hash computation. This is fine in most cases, but if you’re comparing it to a server generated hash from a newer version of .NET or PHP or Java or something similar then your hashes won’t match even if they should.

When you say Cryptography, what are you referring to? Do you want to hash or encrypt/decrypt? Do you want to do it with a shared secret or a public/private key pair like RSA? The original question is far to vague… encryption is supported in Unity but maybe you’re wanting to do something out of the box like BCrypt or Scrypt which aren’t natively supported.

2 Likes

Boss…

Like he said, if you’re looking for some secure data between client and web server, Bcrypt will probably be your best bet. If you’re looking for client/server (game server) encryption and security, like for example, protection against, Cheat Clients, RSA is the way to go.

What are you actually trying todo?

2 Likes

Hi,

Thank you for all the replies.
My scenario is to encrypt a string(Game save data) with a password preferably and save as a text file in the application.datapath

Just to ensure that the player cannot access the data and change it.

You can’t keep players from messing with local files. Even if you encrypt the files, your application will need to be able to encrypt/decrypt it and since the application is running on the user’s computer there will be a way of figuring out how the user can make modifications. They can also cheat by modifying the ram values containing currency, score etc. with applications like cheat engine.

If you want to avoid this kind of cheating, your game needs to run on a server which validates the actions of the player and only provides the information the player should have access to.

That being said, if you just want to have modifying save files require more effort, here are some pretty simple things you can do (pick one or, I guess, more than one):

  • If your save files is in a human-readable format, you can do a Base64 encoding to make it non-readable and difficult to modify, as it requires the user to decode it, make the changes and then reencode.
  • You can do a simple AES encoding to “password-protect” the save file. The password will be contained in your application, so a user will be able to figure it out, but perhaps it requires more effort than they are willing to do.
  • You can write a CRC at the end of the file and when loading the file make sure that it matches the content. That way, when the user changes something, they will have to recalculate a CRC and insert it at the correct position in the file. This is difficult if you also salt the contents, especially if the user does not know that the check is there.
  • Zip the filestream with fastLZ or some of the other readily available compression algorithms.
4 Likes

Why?

Is there data in there that is super critical?

Why block players from cheating?

IMO, if a player wants to cheat, they should be allowed to cheat as much as they want. I remember when games would release with their ‘debug’ modes still in tact and available to tinker with in a released version of the game. They were fun, and allowed for good times.

The only time I can think of that cheating needs to be thwarted is in an online multiplayer setup where cheaters might be pitted against non-cheaters, giving an unfair advantage to the cheating player. This sort of data shouldn’t be stored with the client, and instead on the server.

3 Likes

Hey,

Thanks for the reply. And i know that players will cheat no matter what. Even i have done that Cheat engine value changes long time back. What i really wanted is just to make sure its hard for them to do it… I am okay with 2/100 players changing the save file, but not more.
And i was actually planning to go with AES encoding to password protect. But the FastLZ zip filestream added to it should be really good.

Hey lordofduct,

I am saving data which stores and tells the game what all in-app purchases are made for map unlock. I am right now not planning to go for a server side save. The best i could think of is encrypting the data so that its not easy to hack.

I would not mind letting the user cheat if its just God-Mode or No-Clip like we had in old games. But since its a in-app purchase related save. I really would not want to user to try change it.

Thanks.

In my personal opinion, it would be best to store that on a server, and for more reasons than just security. If it’s stored locally, and they switch to another device, then they no longer have their purchases.
I heard somewhere, that anything you don’t want users to touch, you don’t store locally.

If you encrypt something yourself wont it be passed through the stack and then person trying to access the information will still be able to obtain the information?

Be sure to change the key.

1 Like

Hey,
The game right now does not feature any login functionality. I don’t see why user would expect the same game data on a different device.
When I bring in a login functionality ill move my save data to sever.

If I’m spending money, I expect to have a login that allows me to move my stuff to another device.

I wouldn’t be OK if I bought a game on Steam, and found it I could only play it on the specific computer I bought it on.

Or more annoyingly if it was a phone, since many people swap out phones rather frequently… buy a bunch of powerups for candy-crush, to then get a new iphone, and find out all those power-ups are now gone. I’d be pissed!

If security is what you’re looking for, and you plan to put in a login in the future… why not just do it now, rather than waste your time writing encryption that will just be ripped out in the end.

3 Likes

Example:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Security.Cryptography;
using System.IO;

public class Cryptography : MonoBehaviour
{
    byte[] Encode(byte[] bytes, byte[] key, byte[] vector)
    {
        Aes aes = Aes.Create();
        ICryptoTransform encryptor = aes.CreateEncryptor(key, vector);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(bytes, 0, bytes.Length);
        cryptoStream.Close();
        return memoryStream.ToArray();
    }

    byte[] Decode(byte[] bytes, byte[] key, byte[] vector)
    {
        Aes aes = Aes.Create();
        ICryptoTransform decryptor = aes.CreateDecryptor(key, vector);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write);
        cryptoStream.Write(bytes, 0, bytes.Length);
        cryptoStream.Close();
        return memoryStream.ToArray();
    }

    void Start()
    {
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes("This is a secret message!");
        byte[] key = new byte[16] { 25, 197, 154, 211, 240, 223, 182, 197, 205, 16, 147, 190, 55, 126, 152, 47 }; // The secret key to use for the symmetric algorithm.
        byte[] iv = new byte[16] { 101, 56, 27, 187, 183, 147, 214, 82, 84, 133, 193, 167, 118, 147, 253, 18 }; // The initialization vector to use for the symmetric algorithm.
        byte[] encrypted = Encode(bytes, key, iv);
        //File.WriteAllBytes(Path.Combine(Application.streamingAssetsPath, "config.dat"), encrypted);
        byte[] decrypted = Decode(encrypted, key, iv);
        //decrypted = Decode(File.ReadAllBytes(Path.Combine(Application.streamingAssetsPath, "config.dat")), key, iv);
        Debug.Log (System.Text.Encoding.UTF8.GetString(decrypted));
    }
}