解密文件流时出错(CryptographicException:错误的PKCS7填充。无效长度0)

时间:2016-06-10 10:05:03

标签: c# .net encryption unity3d

过去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");
        }

    }
}

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

2 个答案:

答案 0 :(得分:0)

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

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

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

请注意文件扩展名的区别?

作为旁注,你无法阻止玩家作弊。在代码中嵌入加密密钥是 security by obscurity 。它可能会阻止休闲玩家作弊,但任何拥有一点知识的人都可以通过反编译器轻松提取密钥。

答案 1 :(得分:0)

所以,我确实将加密功能与加密功能分开,并对加密功能进行了解密,并修改了一下代码,所以实际上序列化文件首先关闭,然后加密;在解密文件之前,先对其进行解密,然后再对其进行反序列化。

现在它运作正常;花了一点但是已经完成了。我不知道为什么我得到那个错误,在反序列化时,有助于理解为什么会发生这种错误,但至少我现在有一个工作函数用于保存和加载,并且仍然保持保存文件免受偶尔骗子的影响。