繁体   English   中英

Unity C#加密错误

[英]Unity C# Encryption Error

我在Unity中编写了一个实际的游戏,我想用此代码保护GameData。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;
using System.Text;
using System.Security.Cryptography;
using System.Linq;

public class Data : MonoBehaviour {

static readonly string PasswordHash = "P@@Sw0rd";
static readonly string SaltKey = "S@LT&KEY";
static readonly string VIKey = "@1B2c3D4e5F6g7H8";

public GameObject dirtBlock;

public void Save(){

    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Open(Application.persistentDataPath + "/playerData.dat",FileMode.Open);

    PlayerData data = new PlayerData();
    data.dirtCount = dirtBlock.GetComponent<BlockHandler>().blockCount;
    data.stoneCount = 0;
    data.ironCount = 0;

    bf.Serialize(file,Encrypt(ToByteArray(data)));
    file.Close();

}

public void Load(){

    if(File.Exists(Application.persistentDataPath + "/playerData.dat")){

        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Open(Application.persistentDataPath + "/playerData.dat",FileMode.Open);
        PlayerData data = FromByteArray<PlayerData>(Decrypt(bf.Deserialize(file).ToString()));
        file.Close();

        dirtBlock.GetComponent<BlockHandler>().blockCount = data.dirtCount;

    } else {
        FileStream file = File.Create(Application.persistentDataPath + "/playerData.dat");
        file.Close();
        this.Save();
        this.Load();
    }

}

public static string Encrypt(byte[] plainTextBytes){

    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
    var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));

    byte[] cipherTextBytes;

    using (var memoryStream = new MemoryStream()){

        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)){

            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            cipherTextBytes = memoryStream.ToArray();
            cryptoStream.Close();

        }

        memoryStream.Close();

    }

    return Convert.ToBase64String(cipherTextBytes);

}

public static byte[] Decrypt(string encryptedText){

    byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };

    var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
    var memoryStream = new MemoryStream(cipherTextBytes);
    var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
    byte[] plainTextBytes = new byte[cipherTextBytes.Length];

    memoryStream.Close();
    cryptoStream.Close();
    return plainTextBytes;

}


public byte[] ToByteArray<T>(T obj){

    if(obj == null){
        return null;
    }
    BinaryFormatter bf = new BinaryFormatter();
    using(MemoryStream ms = new MemoryStream()){
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}

public T FromByteArray<T>(byte[] data){
    if(data == null){
        return default(T);
    }

    BinaryFormatter bf = new BinaryFormatter();
    using(MemoryStream ms = new MemoryStream(data)){
        object obj = bf.Deserialize(ms);
        return (T)obj;
    }
}

}

[System.Serializable]
public class PlayerData {

public float dirtCount;
public float stoneCount;
public float ironCount;

}

昨天工作正常,但今天我不知道为什么,我收到此错误消息

SerializationException:意外的二进制元素:0 System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject(BinaryElement元素,System.IO.BinaryReader读取器,System.Int64&objectId,System.Object&值,System.Runtime.Serialization.SerializationInfo&info) (位于/Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:254)System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject(BinaryElement元素,System.IO.BinaryReader读取器)(位于/Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:130)System.Runtime.Serialization。 Formatters.Binary.ObjectReader.ReadObjectGraph(BinaryElement元素,System.IO.BinaryReader阅读器,布尔型readHeaders,System.Object&结果,System.Runtime.Remoting.Messaging.Header []&标头)(位于/ Users / builduser / buildslave / mono /build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/Obj ectReader.cs:104)System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize(System.IO.Stream serializationStream,System.Runtime.Remoting.Messaging.HeaderHandler处理程序)(在/ Users / builduser / buildslave / monoslav / build /mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179)System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(System.IO.Stream serializationStream)(在/ Users / builduser中) /buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136)Data.FromByteArray [PlayerData](System.Byte []数据)(在Assets / Scripts / Player中) /Data.cs:119)Data.Load()(位于Assets / Scripts / Player / Data.cs:40)

我搜索了4小时的网络搜索,但找不到该问题的解决方案。 我希望有人能帮助我。

在对您的代码进行一些测试之后,我最终使用了这两种方法。

我认为您代码的主要问题是Decrypt ,它从未使用plainTextBytes做任何事情。

private static string Encrypt(byte[] plainTextBytes)
{
    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
    var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));

    byte[] cipherTextBytes;

    using (var memoryStream = new MemoryStream())
    {
        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
        {
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            cipherTextBytes = memoryStream.ToArray();
        }
    }

    return Convert.ToBase64String(cipherTextBytes);
}

解码

public static byte[] Decrypt(string base64)
{
    byte[] cipherTextBytes = Convert.FromBase64String(base64);
    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };

    var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
    using (var memoryStream = new MemoryStream(cipherTextBytes))
    {
        using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        {
            using (BinaryReader srDecrypt = new BinaryReader(cryptoStream))
            {
                return srDecrypt.ReadBytes(cipherTextBytes.Length);
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM