Search Unity

Secured PlayerPrefs - Release

Discussion in 'Assets and Asset Store' started by Taliwut, Nov 7, 2012.

  1. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Hi Unity developpers !

    I'm releasing a Secured PlayerPrefs utility in the asset store today, you can get it here - http://u3d.as/content/taliwut/secured-player-prefs

    It allows you to secure stored data in your game, and avoid problems with players cheating or trying to get free stuff by just modifying some file or system preferences.

    For example, I'm working on a freemium game (the game is free, but you can buy stuff in it). I need to store somewhere secure which items the user bought. If I was using PlayerPrefs a malicious player could edit registry in Windows, or an ASCII file in OS X, Android and iOS. To prevent this, I developped "Secured PlayerPrefs", it acts like PlayerPrefs but it stores a crypted and signed file.


    • It prevents someone who wants to cheat or "steal" items and virtual money.
    • It prevents people to exchange or copy their backup, to give items and virtual money to anyone else. (This is done by a 2-keys algorithm, the first key is defined in your program, the second is defined by the device itself)


    If you need support or if you have feature requests, contact me here or go to http://taliwut.tumblr.com
     
  2. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi Taliwut,

    nice approach to make playerprefs more secure! Just a question out of interest. On your Asset Store main image, I can see there's a secret key hardcoded in the script. Wouldn't it be possible to decompile the game code, get this key and reverse engineer the other key so they match?

    Thanks.
     
  3. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Yes it's possible to decompile the game code and get the key. But it's very difficult to use this key to generate new valid saves.
     
  4. xandeck

    xandeck

    Joined:
    Apr 2, 2009
    Posts:
    563
    Following this... :)
     
  5. derkoi

    derkoi

    Joined:
    Jul 3, 2012
    Posts:
    2,260
    This sounds very interesting. How do we use it? Same as saving regular Playerprefs?
     
  6. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
  7. derkoi

    derkoi

    Joined:
    Jul 3, 2012
    Posts:
    2,260
    Excellent. Purchased! :)
     
  8. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Thanks !

    I'm waiting for feature requests ;)
     
  9. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
  10. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Thanks, good suggestion ! Hope to announce you the next version soon ;)
     
  11. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
  12. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    I just submitted a new version to the asset store with these new methods:

    Code (csharp):
    1.  
    2.     void SetBool(string key, bool newValue)
    3.     bool GetBool(string key, bool defaultValue)
    4.     void SetIntArray(string key, int[] newValue)
    5.     int[] GetIntArray(string key, int[] defaultValue)
    6.     void SetStringArray(string key, string[] newValue)
    7.     string[] GetStringArray(string key, string[] defaultValue)
    8.     void SetFloatArray(string key, float[] newValue)
    9.     float[] GetFloatArray(string key, float[] defaultValue)
    10.     void SetVector2(string key, Vector2 newValue)
    11.     Vector2 GetVector2(string key, Vector2 defaultValue)
    12.     void SetVector3(string key, Vector3 newValue)
    13.     Vector3 GetVector3(string key, Vector3 defaultValue)
    14.     void SetColor(string key, Color newValue)
    15.     Color GetColor(string key, Color defaultValue)
    16.     void SetQuaternion(string key, Quaternion newValue)
    17.     Quaternion GetQuaternion(string key, Quaternion defaultValue)
    18.  
    19.     // Return a JSON string representation of all keys and values stored.
    20.     // Used if you want to synchronize over network.
    21.     string ToJson()
    22.  
     
  13. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Version 1.3 has been accepted by the Unity team. You can update it on the asset store !
     
  14. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Nice work... Seems to be dll based, so few Q's before buying this...

    * I assume fully tested on iOS Android?
    * Will you support Flash WP8 (When it comes out)?
    * Are you using playerprefs or your own file solution to store encrypted data?
    * Are you using Unity's device id (SystemInfo.deviceUniqueIdentifier) API to generate 2nd (device) key or something else?

    Thanks in advance...
     
  15. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    It has been tested on iOS, Android, OS X and Windows

    It should work everywhere, but I'm trying to test released version all devices I own.

    I'm using my own file solution to store encrypted data. I also store versions history, and rollback to previous versions if the player try to manipulate the main save game (he will not be able to do it, so he will corrupt it).

    Yes I'm using a compound key that is generated from SystemInfo.deviceUniqueIdentifier so users can't exchange their save games.

    Note: I'm planning to add a secured server backup / restore.
     
    AlenH likes this.
  16. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Thanks for the replies, you'll probably have a new customer soon.... :)
     
  17. RandAlThor

    RandAlThor

    Joined:
    Dec 2, 2007
    Posts:
    1,293
    I am interested in using this for ios and with some prime31 plugins to use icloud and iap.
    Does "secured playerprefs" will work with them?
     
  18. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    First, I didn't tried iap and icloud with Secure PlayerPrefs.

    - I see no problems with iap.

    - But with icloud, I see one big problem: if the user got 2 iOS devices connected on the same iCloud account, and if you try to synchronize the output files from Secured PlayerPrefs plugin, it will not work because of the different device ids. A solution could be the integration of an optional "prime 31 icloud" support in Secured PlayerPrefs. But I don't know if iCloud data storage is secure (I hope so) or if it could be a source of data manipulation.
     
  19. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Hi there,

    I'm looking for beta testers for the new feature of "Secured PlayerPrefs" plugin: server synchonization. Contact me directly at taliwut gmail com or via PM. Users who bought it have priority.

    Thanks !
     
  20. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
  21. Detocroix

    Detocroix

    Joined:
    Jul 2, 2010
    Posts:
    75
    Does Secured PlayerPrefs save to file on PC or to registry?
     
  22. spartan

    spartan

    Joined:
    Mar 10, 2010
    Posts:
    174
    @Taliwut your plugin v1.3 is crashing on the device (iPhone) with iOS SDK 6, Unity 3.5.7. Tested with your sample scene, no changes made.
     
  23. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    On all platforms it saves to file.
     
  24. Detocroix

    Detocroix

    Joined:
    Jul 2, 2010
    Posts:
    75
    Cheers! Buying :)
     
  25. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    After some investigation with @spartan.

    From the Unity docs : http://docs.unity3d.com/Documentation/Manual/iphone-playerSizeOptimization.html
    "Use micro mscorlib level: a special, smaller version of mscorlib is used. Some components are removed from this library, for example, Security, Reflection.Emit, Remoting, non Gregorian calendars, etc. Also, interdependencies between internal components are minimized"

    SecuredPlayerPrefs plugin is intensively using the "System.Security.Cryptography" methods that are stripped in micro mscorlib.

    So currently you can't use the "micro mscorlib" stripping level with Secured PlayerPrefs Plugins.
     
  26. froodydude

    froodydude

    Joined:
    Sep 22, 2011
    Posts:
    27
    Add a link.xml file to Assets and add this:

    <linker>
    <assembly fullname="mscorlib">
    <namespace fullname="System.Security.Cryptography" preserve="all"/>
    </assembly>
    </linker>

    That should stop it being stripped and you can still use micro mscorlib
     
  27. froodydude

    froodydude

    Joined:
    Sep 22, 2011
    Posts:
    27
    Tailwut, I want to use your plugin on a project for a big publisher who likes to read license agreements before using such things. Can you point me at one please because I can't obviously see one anywhere?

    Also can you say what kind of cryptography it uses? There is a box in iTunes you have to tick if your app uses cryptography but only certain techniques are applicable. You don't want your users having to tick this box!
     
    Last edited: Dec 21, 2012
  28. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    I'll send you a copy. Give me your email address in PM.

    If you're working on a game and you're using Secured PlayerPrefs plugin to store encrypted users data (ie "support of entertainement"), the tick in iTunes doesn't need to be checked, because your app qualify for an exemption of CCATS cf. http://www.bis.doc.gov/encryption/flowchart1.pdf and http://www.bis.doc.gov/encryption/question6sub_2.htm

    If you're trying to hijack the plugin to send private message or I don't know what, yes you will need to declare it by checking the tick in the iTunes store.
     
  29. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Thanks a lot for this tip !
     
  30. froodydude

    froodydude

    Joined:
    Sep 22, 2011
    Posts:
    27
    Thanks for the info Taliwut, PM on its way.
     
  31. PabloAM

    PabloAM

    Joined:
    Dec 25, 2012
    Posts:
    35
    I would like to try that new feature.

    What is the server to synchonization? Self hosted or iCloud?

    Thanks
     
  32. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    Hi, I've just bought the plugin and I just need to clarify a few things as to how I should use it.

    I have 2 versions of all my games, a full paid version and a free version with in-app purchases to unlock features or content.

    I use PlayerPrefs to store the fact something is owned or purchased. So a full priced game sets all the items to owned by setting ints in Playerprefs somewhere early in startup. The game then just reads those to see if the player owns the items.

    The free version waits for a purchase to be successful before setting the int in playerprefs.

    I think my worry and question is how will this plugin protect my app against copying exactly? On the paid version of my game it always sets the playerprefs ints to owned so having a secure version doesn't seem like it will help at all or am I missing something?
     
    Last edited: Dec 31, 2012
  33. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    If you're talking about pirating the full priced copy, Secured PlayerPrefs can't help at all. This is not a DRM.

    But if you're talking about copying save files:

    The saved file that stores Secured PlayerPrefs data can't be copied from a device to another. In fact it can be physically copied form a device to another but the DeviceUniqueID is used to encrypt / decrypt data, so if a file has been saved by Bob's device, it can't be read by Alice's device.
     
  34. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    Hi, I am getting an exception whenever I call SecuredPlayerPrefs.Save();

    The exact error is:-

    Code (csharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. SecuredPlayerPrefs.signHashtable ()
    3. SecuredPlayerPrefs.Save ()
    4. HighScores.AddHighScore (System.String name, Int32 score) (at Assets/Scripts/CSharpScripts/HighScores.cs:816)
    5. HighScores.Start () (at Assets/Scripts/CSharpScripts/HighScores.cs:233)
    I set the key on the 1st function in my 1st scene. The exception happens when I load a new scene (highscores scene),
    I set some secureplayerprefs then call save. Any ideas what's wrong?

    *Update, it stops giving the exception after a while so it could be the 1st time it tries to save. Where exactly does it save this secured file so I can delete it and try again?
     
    Last edited: Jan 2, 2013
  35. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    Anybody there? I still have the exception.
     
  36. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Hi,

    You must call "SecuredPlayerPrefs.SetSecretKey(string)" each time you load a scene (I can't make SecuredPlayerPrefs a Singleton)
     
  37. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    It saves a "SecuredPlayerPrefs" file in the directory pointed by: Application.persistentDataPath (actual directory depends on architecture and run method)

    For instance, when it's launched in the Unity Editor on a Mac, it saves a file at ~/Library/Caches/taliwut/unity_secured_player_prefs/SecuredPlayerPrefs
     
  38. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,548
    A question ,if user uninstall the app and reinstall it later, does the data saved in the file gets wiped out?
     
  39. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    On Android yes, on iOS yes unless the user uses iCloud. That's why I'm working on server synchronization.
     
  40. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    I'm still getting exceptions on Andoid, here is the logcat output for the error:-


    NullReferenceException: Object reference not set to an instance of an object
    I/Unity (23856): at SecuredPlayerPrefs.signHashtable () [0x00000] in <filename unknown>:0
    I/Unity (23856): at SecuredPlayerPrefs.Save () [0x00000] in <filename unknown>:0
    I/Unity (23856): at HighScores.check_achievements () [0x00000] in <filename unknown>:0
    I/Unity (23856): at HighScores.OnGUI () [0x00000] in <filename unknown>:0

    Here is my code:-
    Code (csharp):
    1.    SecuredPlayerPrefs.SetSecretKey("hFjkgtu0123DFGcdq9QsS");
    2.    SecuredPlayerPrefs.SetString("HScoreName",newName);
    3.    SecuredPlayerPrefs.Save();
    if I take out the save I don't get the exception.
     
  41. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Are you using the micro mscorlib stripping level ? If yes, please see a messages above, else send me an email taliwut @ gmail com I'll send you a debug version to get more details.
     
  42. shb

    shb

    Joined:
    Oct 7, 2012
    Posts:
    23
    Hi,
    getting int or string array doesn't seem to work correctly.
    When I save new array to prefs, getting it back seems to work,
    but when i try to getting it after stopping restarting the application,
    it says value is not an array and it will return default value.


    Here's my simple test code.

    string[] defaultValue = {"1","1"};
    string[] newValue = {"2","2"};


    Debug.Log("str= " + SecuredPlayerPrefs.ToPrettyString());

    string[] myarray = SecuredPlayerPrefs.GetStringArray("mykey", defaultValue);

    print (SecuredPlayerPrefsTests.ToStringArray(new ArrayList(myarray)));

    SecuredPlayerPrefs.SetStringArray("mykey", newValue);
    SecuredPlayerPrefs.Save();

    After stopping and restarting the application,
    SecuredPlayerPrefs.ToPrettyString shows its content and it seems to work.
    I'm supposed to have new value but
    I got default array.


    str= {"mykey": [2, 2]}
    UnityEngine.Debug:Log(Object)

    Error: mykey is not a string[] - return defaultValue
    SecuredPlayerPrefs:GetStringArray(String, String[])

    Any clue?
     
  43. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    Did you get a reply or fix for this?
     
  44. PabloAM

    PabloAM

    Joined:
    Dec 25, 2012
    Posts:
    35
    Hello I´m getting a error trying to get a Vector2.

    This is my code:
    Saving: (Is OK) totalScores and totalStars are Floats.
    Code (csharp):
    1. Vector2 totals = new Vector2(totalScores,totalStars);
    2. SecuredPlayerPrefs.SetVector2("world"+Globals.currentWorld+"lvl"+Globals.currentLevel,totals);     
    3.  
    Getting:
    Code (csharp):
    1. Vector2 infoLevel = SecuredPlayerPrefs.GetVector2("world"+Globals.currentWorld+"lvl"+(i+1), new Vector2(-1f,0f));
    2.  
    This is the error:
    Code (csharp):
    1. Error: world1lvl1 is not a float[] - return defaultValue
    2. UnityEngine.Debug:Log(Object)
    3. SecuredPlayerPrefs:GetFloatArray(String, Single[])
    4. SecuredPlayerPrefs:GetVector2(String, Vector2)
    5. LevelSelector:loadlvls(Int32) (at Assets/Scripts/LevelSelector/LevelSelector.cs:98)
    6. LevelSelector:loadLevels() (at Assets/Scripts/LevelSelector/LevelSelector.cs:55)
    7.  
    What could it be?¿
     
  45. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Hi, sorry guys for not responding. I don't know why but I don't receive notifications by email...

    I'm currently working with @PabloAM to find where his problem come from.

    After that, I will investigate on @shb issue.
     
  46. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    The new 1.4 version of the plugin is waiting for approval in the asset store. If you don't want to wait, email me please.
     
  47. PabloAM

    PabloAM

    Joined:
    Dec 25, 2012
    Posts:
    35
    Thanks Taliwut, now works perfect :)

    Thanks to answer quickly :)

    The problem was resolved with that new version.
     
  48. Taliwut

    Taliwut

    Joined:
    Sep 27, 2012
    Posts:
    34
    Version 1.4.1 has been approved by the Unity asset store team. This version fix bugs and it's compatible with Unity 3.5.7+ and Unity 4.x
     
  49. artonator

    artonator

    Joined:
    Sep 12, 2009
    Posts:
    69
    What happen when user remove my app and re install my app again, Will user be able to restore all the data back to the new version( like earned coins, purchased items, unlocked levels?). Current PlayerPrefs seems cant protect user data this case. Well.. without using server solution.

    Cheers,

    Arthur.
     
  50. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    What exactly was the problem as I have a game on the store built with 3.5.7 and using your last version of securedplayerprefs.