当前位置: 首页 > 知识库问答 >
问题:

Unity C#加密错误

宰修能
2023-03-14

我写一个统一的实际游戏,我想用这个代码来保护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;

}

昨天它工作正常,但今天,我不知道为什么,我得到这个错误消息

序列化异常:意外的二进制元素:0系统。运行时。序列化。格式。二进制。对象读者。读者对象(二进制元素,系统。IO。二进制读者,系统。int64

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

共有1个答案

晏晨朗
2023-03-14

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

我认为你的代码的主要问题是解密,它从来没有对明文字节-数组做过任何事情。

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);
            }
        }
    }
}
 类似资料:
  • 我目前正在尝试使用OpenSSL加密二进制文件(它是项目的一部分,必须使用OpenSSL)。我设法安装了OpenSSL并将其与Visual Studio 2010链接。 在完成我的程序时,我没有得到任何带下划线的错误,但是在编译时,我得到了以下结果 有人知道如何解决这个错误吗?

  • 问题内容: 我正在使用静态方法在类中使用javax.crypto加密和解密消息。我有2个使用cipher和dcipher的静态方法,以完成他们应该做的事情,我需要初始化一些变量(也是静态的)。但是,当我尝试使用它时,我得到的InvalidKeyException与我提供给ecipher.init(…)的参数。我找不到原因。这是代码: 问题答案: AES-256(和AES-192)要求为JRE安装无

  • 请帮助我识别以下RSA加密代码中的问题

  • 我目前正在用java编写一个加密消息传递服务,我使用的是bouncycastle PGP库。我编写了一个生成密钥对的测试程序,并对消息进行加密/解密。这已经工作了一段时间,但它最近在解密阶段停止了,给了我一个InvalidKeyException。 我做了一些研究,下载了JCE.jar文件,并将它们导入到我的项目中(通过Eclipse Project->Properties->add extern

  • 在一个做其他事情的大型应用程序中——我需要加密和解密一个文件。所以我一直在四处寻找,并实现了这两个核心功能,基本上使用RSA密钥包装一个随机的AES密钥来加密一个文件。对称键和iv被写入文件的开头。 我在下面的解密函数部分得到一个异常(“javax.crypto.BadPaddingException:Decryption error”)。在肯安迪夫线路上——doFinal。具体来说,这一行是异常

  • 问题内容: 我已经以加密格式将用户密码存储在数据库中。但是,现在,当用户想要登录并尝试输入其原始密码时,该代码始终会将输入的(原始)密码与数据库中存储的加密版本进行比较,从而导致登录失败。 请告诉我如何比较输入的(原始)密码和存储在数据库中的加密密码。 问题答案: 几乎可以肯定,您应该对密码进行 哈希处理 ,而不是使用可逆加密。您可能还需要 用盐 来做…在这种情况下,正确的步骤是: 查找最初对密码