0

I use Asymmetric Encryption from Here and I was able to get things working perfectly as I turn my classes that hold data to Json data with JsonUtility.ToJson() and then I use the Encryption in the link above.

I use to use the C# Serializer but ran into issues so I was directed to using this which is working out great but when I changed one of my saving systems with this I run into the error of "Max Length is 117" which makes me think I am saving too much in my class (I have variables for the Transform, Sprite Renderer and Collider2D) so I increased my keySize variable (using 1024 for this and all my other areas I use this as well.) from 1024 to 2048 in my EncryptText() and DecryptText() methods in the Asymmetric Encryption link and saw what I thought was working as I was getting to the point where I had a big enough size to hold the data from what one of the throw error messages was telling me.

I then reached a point where it said "CryptographicException:message too long" and now I am wondering, "how do I fix this?". This makes me worry if I put this in one of my projects in the Unity Store to where people will run into the issue of saving too much in a scene (and it was about 4 GameObjects being saved lol... :( ). Even if I broke what I saved up into multiple classes and saved it that fashion I feel like the size issue could potentially be a red alert.

Any ideas on how to approach this situation?

Code :

public class State_Manager : MonoBehaviour {

    public void Save()
    {
        // IF we have nothing to save then don't save.
        if(transformStateList.Count == 0){
            return;
        }
        // Create a new State_Data.
        State_Data data = new State_Data ();
        // Loop the amount of the size of the List.
        for(int i = 0; i < transformStateList.Count; i++){
            // Create a new Object_Data struct.
            Object_Data objectData = new Object_Data ();
            // Store our data in our data structure.
            objectData.StoreData(transformStateList[i]);
            // Add it to the list.
            data.objectData.Add (objectData);
        }
        // Turn the Store_Data into Json data.
        string stateToJson = JsonUtility.ToJson(data);
        // Encrypt the Json data.
        string encryptedJson = AsymmetricEncryption.EncryptText (stateToJson, keySize, PlayerPrefs.GetString("PK"));
        // Save the information.
        PlayerPrefs.SetString("State", encryptedJson);
    }

    [System.Serializable]
    class State_Data
    {   
        public List<Object_Data> objectData = new List<Object_Data> ();
    }
}

[Serializable]
public class Object_Data {

    // Transform information.
    public bool active;
    public string name;
    public int layer;
    public float xPos;
    public float yPos;
    public float zPos;

    // Sprite Renderer Information
    public string spriteName = "";
    public string sortLayerName = "";
    public int sortLayerOrder = 0;

    // Collider2D Information.
    public bool isCollider = false;
    public bool activeCollider;

    public void StoreData(GameObject go){
        // Save the activeness.
        active = go.activeInHierarchy;
        // Save the GameObjects name.
        name = go.name;
        // Save the GameObjects layer.
        layer = go.layer;
        // Save the GameObjects position.
        xPos = go.transform.position.x;
        yPos = go.transform.position.y;
        zPos = go.transform.position.z;
        // IF this GameObject has a sprite renderer,
        // ELES it doesn't have a sprite renderer.
        if (go.GetComponent<SpriteRenderer> () != null) {
            // Save the sprite name, sorting layer name and the sorting layer order.
            spriteName = go.GetComponent<SpriteRenderer> ().sprite.name;
            sortLayerName = go.GetComponent<SpriteRenderer> ().sortingLayerName;
            sortLayerOrder = go.GetComponent<SpriteRenderer> ().sortingOrder;
        }
        // IF there is a Collider2D attached,
        // ELSE there is not a Collider2D attached.
        if (go.GetComponent<Collider2D> () != null) {
            isCollider = true;
            activeCollider = go.GetComponent<Collider2D> ().enabled;
        }
    }
}
JoeyL
  • 1,295
  • 7
  • 28
  • 50
  • Why did you choose asymmetric encryption, do you really need a private and public key? In general asymmetric encryption encryption is only used when a private and public key pair are required, otherwise symmetric key encryption is used, generally AES. – zaph Oct 22 '16 at 00:51
  • Due to ignorance. I am learning encryption and just trying to figure it out. I was referred to the link in my post from someone else that answered one of my previous questions and told me that link is good for security. So I tried to understand it the best I could and tried to get it to work, little did I know I was going to run into that error. – JoeyL Oct 22 '16 at 18:25
  • If you just want to get something to work and be secure consider [RNCryptor-cs](https://github.com/RNCryptor/RNCryptor-cs). At least take a look at it and the [RNCryptor-Spec](https://github.com/RNCryptor/RNCryptor-Spec) to see what is needed to do it right. – zaph Oct 22 '16 at 18:38
  • @zaph Thanks for the quick response zaph. I have seen more people talk about AES than others so I think I will give AES a shot. **couple hours go by**, I went and tried this out [AES](http://www.aspsnippets.com/Articles/AES-Encryption-Decryption-Cryptography-Tutorial-with-example-in-ASPNet-using-C-and-VBNet.aspx). Basically I am just using the Encrypt and Decrypt methods and inputting my json string into Encrypt method and the encryptedJson into the Decrypt() method and so far everything is working! I don't even need that AsymmetricEncryption class do I? – JoeyL Oct 22 '16 at 21:02
  • @zaph based on what I said in my last comment would you say that I atleast have a grasp on using the scripts correctly? I will dive into more of it later but so long as I am on a good start this will help. Also, is there anything I need to look out for with using this to prevent running into any errors like I did before? – JoeyL Oct 22 '16 at 21:10
  • There are many potential issues depending on the use. Remember the propblem moved from keeping the data secure to keeping the key secure and that is very hard. – zaph Oct 22 '16 at 21:28
  • @zaph Oh man I think I just had a light bulb even though you and Scott said as an answer/reply and I cant believe I didn't comprehend it before, I guess I just had to beat my head against a wall and just mess around with the code for a bit for it to start coming together. So as for the data you use AES and the key that I use for the AES I would use the Asym Encryption for! So double wrapping for once is good ha! Thanks again zaph for taking the time to help out with my ignorance. – JoeyL Oct 22 '16 at 22:00
  • Unless you need private and public key pair you just use the symmetric key, no need for RSA. What is your use case? – zaph Oct 23 '16 at 00:15
  • @zaph I have a RPG Kit in the Unity store and I have a save system (player equipment/stats, Sprite Renderer, Collider2D, inventory, etc) in it which it is using the Unity C# serializer which is great except when I want to add to the saved class then I run into errors when I deserialize. So I was looking for something more fluid and was shown JsonUtlity. Turned my class info into Json data and was just going to chuck it into PlayerPrefs but I wanted to provide some security to saved data in the project. So then I started getting into encryption and started to learn Asym Encryption then AES. – JoeyL Oct 23 '16 at 01:21

1 Answers1

4

You don't use asymmetric encryption to encrypt large amounts of data. If you have large amounts of data you normally use symmetric encryption then use asymmetric encryption to encrypt the key.

However, that is totally overkill for your purposes. From how your code looks it appears you likey just have two fields for the public and private keys in your player perfs and you are just encrypting a "State" that will be read out later. Don't use asymmetric encryption for that, just use symmetric encryption.

If you really are wanting to use asymmetric encryption what you will need to do is for encryption:

  1. Generate a new random symmetric encryption key every time you encrypt the data.
  2. Encrypt your data symmetrically with the random key.
  3. Encrypt the random key with your public key from the asymmetric encryption.
  4. Store the symmetrically encrypted data and the asymmetrically encrypted random key together somewhere.

For decryption:

  1. Load the symmetrically encrypted data and the asymmetrically encrypted key from somewhere.
  2. Decrypt the asymmetrically encrypted key with your private key from the asymmetric encryption.
  3. Use the decrypted symmetric key to decrypt the data
  4. Use the data.
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431