解密文件流时出错(加密异常:错误的 PKCS7 填充.长度无效 0)



在过去的 2 个小时里,我一直在撞墙,但看不出这里出了什么问题。

为了给你上下文:我创建一个对象,然后序列化它。一切都很好,除了当我用记事本打开文件时,我可以看到里面的数据;我的班级里有敏感数据,可能会被修改,导致玩家作弊。

所以我确实寻找了一个使用CryptoStream和DESCryptoServiceProvider的例子。我可以对文件进行编码,但是当我反序列化它时,我得到

CryptographicException: Bad PKCS7 padding. Invalid length 0.

这是我正在使用的代码;我确实只包含加载并使用加密保存,因为如果我不使用加密,这些功能就可以工作。

public class SaveManager : MonoBehaviour {
    Dictionary<string, object> savedata;
    private string path = Application.persistentDataPath;
    byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8 }; // test
    byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 }; //test
    DESCryptoServiceProvider des = new DESCryptoServiceProvider();
    void Awake () {
        savedata = new Dictionary<string, object>();
    }
    public void SaveGame(string savegame_name)
    {
        FileStream savefile = new FileStream(path + "/" + savegame_name + ".dat", FileMode.Create, FileAccess.Write);
        BinaryFormatter savegame_formatter = new BinaryFormatter();
        savedata = GenerateSaveDataFile(); // this create the save file
        var cryptoStream = new CryptoStream(savefile, des.CreateEncryptor(key, iv), CryptoStreamMode.Write);
        savegame_formatter.Serialize(cryptoStream, savedata);
        savefile.Close();
    }
    public void LoadGame(string savegame_name)
    {  
        BinaryFormatter loadgame_formatter = new BinaryFormatter();
        if (File.Exists(path + "/" + savegame_name + ".dat"))
        {
            Dictionary<string, object> load_file = new Dictionary<string, object>();
            FileStream loadfile = new FileStream(path + "/" + savegame_name + ".dat", FileMode.Open, FileAccess.Read);
            var cryptoStream = new CryptoStream(loadfile, des.CreateDecryptor(key, iv), CryptoStreamMode.Read);
            load_file = (Dictionary<string, object>)loadgame_formatter.Deserialize(cryptoStream);
            // restore data from file
            loadfile.Close();
        }
        else
        {
            Debug.Log("CANNOT FIND FILE");
        }
    }
}

我真的不知道如何检查文件是否正确加密,也不知道如何检查问题是否出在解密上;如果我只是删除加密流并序列化,那么保存和加载都一切正常。

您可能正在尝试解密未加密的(旧)保存文件,该文件在解密时是填充检查的垃圾。

FileStream savefile = new FileStream(path + "/" + savegame_name + ".dat"...

FileStream loadfile = new FileStream(path + "/" + savegame_name + ".dbt"...

注意到文件扩展名的差异了吗?

作为旁注,您无法阻止玩家作弊。在代码中嵌入加密密钥是隐蔽的安全性。它可能会防止休闲玩家作弊,但任何有一点知识的人都可以使用反编译器轻松提取密钥。

所以,我确实将保存函数与加密分开,将加载函数与解密分开,并修改了一点代码,所以实际上序列化文件先关闭,然后加密; 在先解密文件的同时,在反序列化之前。

现在它工作正常;花了一点时间,但它已经完成了。我不知道为什么在反序列化时会出现该错误,这将有助于理解为什么会发生这种情况,但至少我现在有一个用于保存和加载的工作功能,并且仍然保持保存文件免受偶尔作弊。

最新更新