Search Unity

Secured PlayerPrefs (Complete Code)

Discussion in 'Made With Unity' started by johnnydj, Jul 14, 2014.

  1. johnnydj

    johnnydj

    Joined:
    Apr 20, 2012
    Posts:
    211
    I saw that no one posted any secured PlayerPrefs stuff so I decided to share you mine.
    First of all here is the code for Encrypting and Decrypting:

    Code (CSharp):
    1. static readonly string PasswordHash = "yourkey1";
    2.     static readonly string SaltKey = "yourkey2";
    3.     static readonly string VIKey = "yourkey3";
    4.  
    5.     public string Encrypt(string plainText)
    6.     {
    7.         byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
    8.  
    9.         byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    10.         var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
    11.         var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
    12.  
    13.         byte[] cipherTextBytes;
    14.  
    15.         using (var memoryStream = new MemoryStream())
    16.         {
    17.             using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
    18.             {
    19.                 cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
    20.                 cryptoStream.FlushFinalBlock();
    21.                 cipherTextBytes = memoryStream.ToArray();
    22.                 cryptoStream.Close();
    23.             }
    24.             memoryStream.Close();
    25.         }
    26.         return Convert.ToBase64String(cipherTextBytes);
    27.     }
    28.  
    29.     public string Decrypt(string encryptedText)
    30.     {
    31.         byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
    32.         byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    33.         var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
    34.  
    35.         var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
    36.         var memoryStream = new MemoryStream(cipherTextBytes);
    37.         var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
    38.         byte[] plainTextBytes = new byte[cipherTextBytes.Length];
    39.  
    40.         int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
    41.         memoryStream.Close();
    42.         cryptoStream.Close();
    43.         return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
    44.     }
    The first 3 static variable values can be changed to whatever anyone wants.
    Those are the keys that will be used to encrypt and decrypt your data.
    You can place the above code in whatever file you want.
    Don't forget to add these references to it:

    Code (CSharp):
    1. using System;
    2. using System.Security.Cryptography;
    3. using System.IO;
    4. using System.Text;
    When you have all this ready, calling the Encrypt and Decrypt methods is simple.
    Below is a snippet of how to save and load strings to PlayerPrefs with our new encrypted method:

    Code (CSharp):
    1. //this is how we save the data
    2.     public void SaveMyPrefs()
    3.     {
    4.         PlayerPrefs.SetString("newKey", Encrypt("myValueThatIWantToEncrypt"));
    5.     }
    6.  
    7.     //this is how we load the data
    8.     public void LoadMyPrefs()
    9.     {
    10.         Decrypt(PlayerPrefs.GetString("newKey"));
    11.     }
    I hope this helps some of you to secure your data a bit.
    If your game uses Internet connection all the time, you can go even further and store all the keys on different servers.
    When you have to encrypt or decrypt, you can access your keys from the servers and continue the process :D
     
    Rallix, BAIZOR, 00christian00 and 3 others like this.
  2. TiG

    TiG

    Joined:
    Feb 28, 2011
    Posts:
    311
    Nice contribution, thanks
     
  3. _Scott_

    _Scott_

    Joined:
    Aug 16, 2014
    Posts:
    3
    Looks great, works great! Nice job! :)
     
  4. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
  5. Zeblote

    Zeblote

    Joined:
    Feb 8, 2013
    Posts:
    1,102
  6. araz01

    araz01

    Joined:
    Aug 2, 2016
    Posts:
    53
    hi, the code cannot be used in different scripts? how is it done i add the save ethis pref and decrypt it before i save it then ecnrypt it but the code tells me that the encryption and decryption is not correct in some manner and (cant find the file with the encryptions) problems.
     
  7. Pixelith

    Pixelith

    Joined:
    Jun 24, 2014
    Posts:
    577
    What I did was make a DataManagement Script that didn't destroy on load so it's present in all scenes. Then you can just do a static reference in the script so others can access it. That's how I approached it anyways. There might be a better way of doing it
     
  8. araz01

    araz01

    Joined:
    Aug 2, 2016
    Posts:
    53
    ok...I dont know what you said...and I dont know what I said...regardless i fixed the issue with somekind of an md5 check? it shotws the values but if altered it becomes null (i mean if hacked it becomes null) otherwise its all working! its awesome!
     
  9. zexzill

    zexzill

    Joined:
    Mar 6, 2019
    Posts:
    3
    lol i got assignment for this..
     
  10. dazarolar

    dazarolar

    Joined:
    May 8, 2020
    Posts:
    2
    Thanks for your contribution, I will verify it and I think that I will use it.
    Thanks johnnydj.