• Manual
  • API Documentation
  • Extend
  • Encryption

    Show / Hide Table of Contents
    • Introduction
    • Installation
    • Getting Started
    • Demos
    • The Save System API
    • Auto Save
    • Platforms
    • Security
    • Serialization
    • Supported Data Types
    • Migration
    • FAQ
    • Changelog
    • Extend
      • Overview
      • Converter
      • Encryption
      • Storage
    • Guides
      • Overview
      • Configuring Settings
      • Using Auto Save
      • Basic Saving and Loading
      • Saving and Loading Raw Data
      • Deleting the Data
      • Saving and Loading Images
      • Saving and Loading Scene Objects
      • Saving and Loading Assets
      • Saving and Loading Readonly Properties
    • Integrations
      • Overview
      • Google Play Games
      • Xbox Live
      • Bolt
      • Firebase
      • PlayFab
      • PlayMaker
      • Steam Auto-Cloud
      • Steamworks .NET
      • Facepunch Steamworks
      • Text Mesh Pro
    • Storage
      • Overview
      • Backup
      • Catalog
      • Meta Data
      • Built-in Storages
        • File
        • PlayerPrefs
        • Memory
      • Third-party Storages
        • Firebase
          • Realtime Database
          • Cloud Storage
          • Firestore
        • PlayFab
          • Entity Objects
          • Entity Files
          • User Data
        • Steam
          • Steamworks .NET
          • Facepunch Steamworks
        • Google Play
          • Saved Game
        • Xbox Live
          • Connected Storage

    Encryption

    An encryption algorithm implementation gives you full control over the encryption / decryption of data through Streams.

    The system includes Symmetric encryption algorithm built-in, so it is a good inspiration for implementing your own algorithm by implementing the ISaveSystemEncryption:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Security.Cryptography;
    using UnityEngine;
    
    using Bayat.SaveSystem.Storage;
    
    namespace Bayat.SaveSystem.Security
    {
    
        /// <summary>
        /// Save System symmetric algorithm encryption implementation.
        /// </summary>
        public class SaveSystemSymmetricEncryption : ISaveSystemEncryption
        {
    
            /// <summary>
            /// The default symmetric algorithm name.
            /// </summary>
            public const string DefaultAlgorithmName = "aes";
    
            private const int ivSize = 16;
            private const int keySize = 16;
            private const int pwIterations = 100;
    
            public readonly string AlgorithmName = DefaultAlgorithmName;
    
            public SaveSystemSymmetricEncryption() : this(DefaultAlgorithmName)
            {
    
            }
    
            public SaveSystemSymmetricEncryption(string algorithmName)
            {
                if (string.IsNullOrEmpty(algorithmName))
                {
                    this.AlgorithmName = DefaultAlgorithmName;
                }
                else
                {
                    this.AlgorithmName = algorithmName;
                }
            }
    
            /// <summary>
            /// Gets the cryptographic stream by using the given stream for writting encrypted data. (Encrypting)
            /// </summary>
            /// <param name="stream">The raw stream</param>
            /// <param name="password">The encryption password</param>
            /// <returns>A cryptographic stream wrapper which has an underlying <see cref="CryptoStream"/> for writting encrypted data</returns>
            public virtual SaveSystemCryptoStream GetWriteStream(IStorageStream stream, string password)
            {
                var alg = SymmetricAlgorithm.Create(this.AlgorithmName);
                alg.Mode = CipherMode.CBC;
                alg.Padding = PaddingMode.PKCS7;
                alg.GenerateIV();
                var key = new Rfc2898DeriveBytes(password, alg.IV, pwIterations);
                alg.Key = key.GetBytes(keySize);
    
                // Write the IV to the stream
                stream.UnderlyingStream.Write(alg.IV, 0, ivSize);
                var encryptor = alg.CreateEncryptor();
                return new SaveSystemSymmetricCryptoStream(new CryptoStream(stream.UnderlyingStream, encryptor, CryptoStreamMode.Write), alg, encryptor);
            }
    
            /// <summary>
            /// Gets the cryptographic stream by using the given stream for reading encrypted data. (Decrypting)
            /// </summary>
            /// <param name="stream">The raw stream</param>
            /// <param name="password">The decryption password</param>
            /// <returns>A cryptographic stream wrapper which has an underlying <see cref="CryptoStream"/> for reading encrypted data</returns>
            public virtual SaveSystemCryptoStream GetReadStream(IStorageStream stream, string password)
            {
                var alg = SymmetricAlgorithm.Create(this.AlgorithmName);
                alg.Mode = CipherMode.CBC;
                alg.Padding = PaddingMode.PKCS7;
                var thisIV = new byte[ivSize];
    
                // Read the IV from the stream
                stream.UnderlyingStream.Read(thisIV, 0, ivSize);
                alg.IV = thisIV;
    
                var key = new Rfc2898DeriveBytes(password, alg.IV, pwIterations);
                alg.Key = key.GetBytes(keySize);
    
                var decryptor = alg.CreateDecryptor();
                return new SaveSystemSymmetricCryptoStream(new CryptoStream(stream.UnderlyingStream, decryptor, CryptoStreamMode.Read), alg, decryptor);
            }
    
        }
    
        /// <summary>
        /// Save System symmetric encryption crypto stream wrapper.
        /// </summary>
        public class SaveSystemSymmetricCryptoStream : SaveSystemCryptoStream
        {
    
            /// <summary>
            /// The encryption algorithm.
            /// </summary>
            public readonly SymmetricAlgorithm Algorithm;
    
            /// <summary>
            /// The crypto transform, whether is encryptor or decryptor.
            /// </summary>
            public readonly ICryptoTransform CryptoTransform;
    
            public SaveSystemSymmetricCryptoStream(CryptoStream cryptoStream, SymmetricAlgorithm algorithm, ICryptoTransform cryptoTransform) : base(cryptoStream)
            {
                this.Algorithm = algorithm;
                this.CryptoTransform = cryptoTransform;
            }
    
            public override void Dispose()
            {
                base.Dispose();
                this.Algorithm.Dispose();
                this.CryptoTransform.Dispose();
            }
    
        }
    
    }
    

    For using your own custom encryption algorithm, you should do it through programatic interface by setting the SaveSystemSettings.EncryptionAlgorithm property to your own class.

    • Improve this Doc
    • 0 Comments