About Encryption & Decryption
Re: About Encryption & Decryption
Hi there,
The link I sent was for the exception you need to catch, not an example of catching exceptions.
As catching exceptions is a basic part of programming rather than Easy Save, I recommend taking a look at tutorials on catching exceptions to understand how this works, as they're an essential part of coding:
https://www.w3schools.com/cs/cs_exceptions.asp
All the best,
Joel
The link I sent was for the exception you need to catch, not an example of catching exceptions.
As catching exceptions is a basic part of programming rather than Easy Save, I recommend taking a look at tutorials on catching exceptions to understand how this works, as they're an essential part of coding:
https://www.w3schools.com/cs/cs_exceptions.asp
All the best,
Joel
-
- Posts: 29
- Joined: Sat Mar 21, 2020 2:17 pm
Re: About Encryption & Decryption
Hi Joel, hope you are doing well!
I took a break from this for some time... Now I'm back. I did read up on the link you shared (w3schools). It's a good read, thank you!
I also tried it on another phone and I have this new error.
***EDIT01***
I managed to handle the FormatException as mentioned in the very first post of this thread. All the loading will be using example:
Is this how it should be done?
Is there any way to check if a bytes array was password protected and if it was, what was the password it was protected with (for debugging purposes only)?
But how do I handle the new ArgumentException error mentioned above?
***EDIT02***
As mentioned in EDIT01 on how I handle FormatException there's another issue I encounter on further testing.
Is there a way to open encrypted files and then save it without encryption? Why I'm asking is because I need to know if it's doable.
So what I did:
> clear slate: deleted save file
> inspector runtime settings have aes encryption on with a password
> ran the game
> created a save file normally in-game with save functions "ES3.Save<string>("playerNickname", playerNickname);"
> stopped the game
> inspector runtime settings set encryption to none
> ran the game
> loading data works fine due to how I handle the FormatException and load data as mentioned in EDIT01
> but I can no longer save using "ES3.Save<string>("playerNickname", playerNickname);" as it will throw FormatException
I took a break from this for some time... Now I'm back. I did read up on the link you shared (w3schools). It's a good read, thank you!
I also tried it on another phone and I have this new error.
Code: Select all
ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
ES3Internal.ES3Stream.CreateStream (ES3Settings settings, ES3Internal.ES3FileMode fileMode) (at F:/Desktop/Shark Pew Pew/SharkPewPew/Assets/Settings/Asset Store Packages/Easy Save 3/Scripts/Streams/ES3Stream.cs:65)
ES3Reader.Create (ES3Settings settings) (at F:/Desktop/Shark Pew Pew/SharkPewPew/Assets/Settings/Asset Store Packages/Easy Save 3/Scripts/Readers/ES3Reader.cs:342)
ES3.KeyExists (System.String key, ES3Settings settings) (at F:/Desktop/Shark Pew Pew/SharkPewPew/Assets/Settings/Asset Store Packages/Easy Save 3/Scripts/ES3.cs:1097)
ES3.KeyExists (System.String key) (at F:/Desktop/Shark Pew Pew/SharkPewPew/Assets/Settings/Asset Store Packages/Easy Save 3/Scripts/ES3.cs:1066)
User.LoadUser (System.Boolean newEntrySaveDataLocal, System.Boolean newEntrySaveDataCloud) (at F:/Desktop/Shark Pew Pew/SharkPewPew/Assets/Scripts/Game Data Classes/User/User.cs:63)
GameData.Start () (at F:/Desktop/Shark Pew Pew/SharkPewPew/Assets/Scripts/Photon Networking/GameData.cs:62)
Code: Select all
public ES3Settings ES3Settings { get; private set; }
private void SetupEasySaveSettings()
{
// Apply defaults as set within the inspector Runtime Settings of EasySave3.
ES3Settings = new ES3Settings(true);
if (ES3.FileExists())
{
try
{
ES3.KeyExists("test");
}
catch (FormatException)
{
// A FormatException was thrown in EasySave3 from:
// ES3Internal.ES3JSONReader..ctor(System.IO.Stream stream, ES3Settings settings, System.Boolean readHeaderAndFooter)(at Assets / Settings / Asset Store Packages / Easy Save 3 / Scripts / Readers / ES3JSONReader.cs:39)
// The message:
// FormatException("Cannot load from file because the data in it is not JSON data, or the data is encrypted.\nIf the save data is encrypted, please ensure that encryption is enabled when you load, and that you are using the same password used to encrypt the data.");
// Solution:
// Create a new ES3Settings object with password.
Debug.Log($"FormatException - Exception caught. Attempting to load using password.");
ES3Settings = new ES3Settings(ES3.EncryptionType.AES, "JohnnySuperShiningStar");
}
}
}
Code: Select all
playerUserID = ES3.KeyExists("playerUserID", GameData.Instance.ES3Settings) == true ? ES3.Load<string>("playerUserID", GameData.Instance.ES3Settings) : "";
Is there any way to check if a bytes array was password protected and if it was, what was the password it was protected with (for debugging purposes only)?
But how do I handle the new ArgumentException error mentioned above?
***EDIT02***
As mentioned in EDIT01 on how I handle FormatException there's another issue I encounter on further testing.
Is there a way to open encrypted files and then save it without encryption? Why I'm asking is because I need to know if it's doable.
So what I did:
> clear slate: deleted save file
> inspector runtime settings have aes encryption on with a password
> ran the game
> created a save file normally in-game with save functions "ES3.Save<string>("playerNickname", playerNickname);"
> stopped the game
> inspector runtime settings set encryption to none
> ran the game
> loading data works fine due to how I handle the FormatException and load data as mentioned in EDIT01
> but I can no longer save using "ES3.Save<string>("playerNickname", playerNickname);" as it will throw FormatException
Re: About Encryption & Decryption
Hi there,
In your case instead of detecting whether a file is encrypted, you're better off detecting whether the file can be decrypted. For example:
Regarding the format exception, please could you create a brand new project with a basic scene which replicates this and private message it to me so I can take a closer look?
All the best,
Joel
The code you've posted does this.Is there any way to check if a bytes array was password protected
If this were possible then it would be possible for anyone to find out the password, so I'm afraid this isn't possible....and if it was, what was the password it was protected with (for debugging purposes only)?
This is likely because the password doesn't match their password.I also tried it on another phone and I have this new error.
In your case instead of detecting whether a file is encrypted, you're better off detecting whether the file can be decrypted. For example:
Code: Select all
private void SetupEasySaveSettings()
{
// Apply defaults as set within the inspector Runtime Settings of EasySave3.
ES3Settings = new ES3Settings(ES3.Encryption.AES, "JohnnySuperShiningStar");
if (ES3.FileExists())
{
try
{
ES3.KeyExists("test", ES3Settings);
}
catch (Exception e)
{
// If we can't load it with encryption, either the data isn't encrypted, the password is wrong, or the data is corrupt.
// Try loading without encryption to see whether the data is encrypted.
try
{
ES3.KeyExists("test", new ES3Settings(ES3.EncryptionType.None));
}
catch(Exception e)
{
// This means that the issue is that the password was wrong, or the data is corrupted.
// It's impossible to know which is the case as this would make it much easier for hackers to crack the password.
// In this case, just throw an error to the user saying that the password is incorrect or the save file is invalid.
// Most likely the password is incorrect, so enable encryption by default:
ES3Settings = new ES3Settings(ES3.EncryptionType.AES, "JohnnySuperShiningStar");
}
}
}
All the best,
Joel
-
- Posts: 29
- Joined: Sat Mar 21, 2020 2:17 pm
Re: About Encryption & Decryption
Hi Joel... I know this has been a long topic. Again I took a break from this to work on something else.
Getting ES3, my game logics and another third-party cloud saving plugin (not mentioning the name as you removed it the last time) is a big stress.
I have a question. I'm using encryption set in the inspector.
Saving to bytes before pushing to the cloud is this:
Then pulling and reading off from cloud bytes it this:
I'm doing this to read the bytes before encryption was implemeted for testing:
Now when using encryption, obviously the bytes don't make sense. How can decrypt the bytes? I want to view what I'm sending and receiving. This is only for my debug messages.
Getting ES3, my game logics and another third-party cloud saving plugin (not mentioning the name as you removed it the last time) is a big stress.
I'll repro it when everything else fails. Because my project is in a big mess and taking the things out for the repro is another stress.Regarding the format exception, please could you create a brand new project with a basic scene which replicates this and private message it to me so I can take a closer look?
I have a question. I'm using encryption set in the inspector.
Saving to bytes before pushing to the cloud is this:
Code: Select all
...
var cacheSettings = new ES3Settings(ES3.Location.Cache);
ES3.Save<Dictionary<string, string>>("bagInventory", temp, cacheSettings);
byte[] bytes = ES3.LoadRawBytes(cacheSettings);
...
Code: Select all
...
var cacheSettings = new ES3Settings(ES3.Location.Cache);
ES3.SaveRaw(data, cacheSettings);
// Overwrite bag inventory items.
if (ES3.KeyExists("bagInventory", cacheSettings))
{
...
Code: Select all
JUtil.Log(JUtil.LogHandle().Bag, $"<b>Bag ►</b> Attempting to save to cloud. Bytes to save:" +
$"\nConvert.ToBase64String:\n{Convert.ToBase64String(bytes)}" +
//$"\nSystem.Text.Encoding.Default.GetString: {System.Text.Encoding.Default.GetString(bytes)}" +
$"\nSystem.Text.Encoding.UTF8.GetString:\n{System.Text.Encoding.UTF8.GetString(bytes)}");
Re: About Encryption & Decryption
Hi there,
If you want to get the unencrypted bytes you would need to resave the data to a different file with encryption disabled and output this.
One thing to note: you're converting your data to a Base 64 String, when the data is UTF8 encoded. Instead to covert bytes to a string you should do:
All the best,
Joel
If you want to get the unencrypted bytes you would need to resave the data to a different file with encryption disabled and output this.
One thing to note: you're converting your data to a Base 64 String, when the data is UTF8 encoded. Instead to covert bytes to a string you should do:
Code: Select all
var str = cacheSettings.encoding.GetString(bytes);
Joel
-
- Posts: 29
- Joined: Sat Mar 21, 2020 2:17 pm
Re: About Encryption & Decryption
Thank you for:
But both are showing encrypted data. Am I typing my codes wrong?
[EDIT01]
OR... Do you mean I have to do double saving? One encrypted to one file and another unencrypted to another file?
So I changed it something like this now:Code: Select all
var str = cacheSettings.encoding.GetString(bytes);
Code: Select all
public void ReplaceWithCloudSavedData(byte[] data)
{
var cacheSettings = new ES3Settings(ES3.Location.Cache);
ES3.SaveRaw(data, cacheSettings);
JUtil.Log(JUtil.LogHandle().Bag, $"<b>Bag ►</b> Overwriting local data with the data retrieved from cloud. Bytes retrieved:\n{cacheSettings.encoding.GetString(data)}");
var debugSettings = new ES3Settings("Debug", ES3.Location.File, ES3.EncryptionType.None);
ES3.SaveRaw(data, debugSettings);
JUtil.Log(JUtil.LogHandle().Bag, $"<b>Bag ►</b> Overwriting local data with the data retrieved from cloud. Bytes retrieved (decrypted):\n{debugSettings.encoding.GetString(data)}");
...
[EDIT01]
OR... Do you mean I have to do double saving? One encrypted to one file and another unencrypted to another file?
Re: About Encryption & Decryption
This is correct.OR... Do you mean I have to do double saving? One encrypted to one file and another unencrypted to another file?
All the best,
Joel
-
- Posts: 29
- Joined: Sat Mar 21, 2020 2:17 pm
Re: About Encryption & Decryption
Ok. But why is there no way to decrypt it for debugging? The 'Load'/'LoadInto' functions decrypts it so is there no way to actually decrypt all the bytes to a string for easy debugging? I'm a bit confused on this approach.
[EDIT01]
Also, this seems ok when you are preparing to push data to the cloud. You can actually push the bytes and view it unencrypted by double saving.
But on receiving the encrypted bytes from the cloud, how can I then view what I'm receiving?
[EDIT01]
Also, this seems ok when you are preparing to push data to the cloud. You can actually push the bytes and view it unencrypted by double saving.
But on receiving the encrypted bytes from the cloud, how can I then view what I'm receiving?
Re: About Encryption & Decryption
Hi there,
If you private message me your invoice number I can send over an update which adds an ES3.EncryptBytes and ES3.DecryptBytes method which will do what you want.
All the best,
Joel
If you private message me your invoice number I can send over an update which adds an ES3.EncryptBytes and ES3.DecryptBytes method which will do what you want.
All the best,
Joel
-
- Posts: 29
- Joined: Sat Mar 21, 2020 2:17 pm
Re: About Encryption & Decryption
Alright, but hang on. I think I might have found a way.
I update as an '[EDITxx]' once done.
[EDIT01]
Ok it's working now!
I update as an '[EDITxx]' once done.
[EDIT01]
Ok it's working now!
Code: Select all
public void ReplaceWithCloudSavedData(byte[] data)
{
var cacheSettings = new ES3Settings(ES3.Location.Cache);
ES3.SaveRaw(data, cacheSettings);
JUtil.Log(JUtil.LogHandle().Bag, $"<b>Bag ►</b> Overwriting local data with the data retrieved from cloud. Bytes retrieved:\n{cacheSettings.encoding.GetString(data)}");
JUtil.Log(JUtil.LogHandle().Bag, $"<b>Bag ►</b> Overwriting local data with the data retrieved from cloud. Bytes retrieved (decrypted):\n{JUtil.RawBytesDecryptedToString(cacheSettings)}");
...
Code: Select all
//----------------------------------------------------------------
internal static Dictionary<string, ES3File> cachedFiles = new Dictionary<string, ES3File>();
public static string RawBytesDecryptedToString(ES3Settings settings)
{
if (!cachedFiles.TryGetValue(settings.path, out ES3File cachedFile))
{
cachedFile = new ES3File(settings, false);
cachedFiles.Add(settings.path, cachedFile);
}
cachedFile.settings = settings;
var unencryptedSettings = (ES3Settings)settings.Clone();
unencryptedSettings.encryptionType = ES3.EncryptionType.None;
return unencryptedSettings.encoding.GetString(ES3.LoadRawBytes(unencryptedSettings));
}