我正在玩数独游戏,我有一个可以保存的数独游戏列表。我目前有以下序列化程序类来保存游戏:
/// <summary>
/// A method to serialize the game repository
/// </summary>
/// <param name="filename">A string representation of the output file name</param>
/// <param name="savedGameRepository">The saved game repository</param>
public void SerializeRepository(string filename, SavedGameRepository savedGameRepository)
{
using (Stream stream = File.Open(filename, FileMode.OpenOrCreate))
{
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, savedGameRepository);
}
}
/// <summary>
/// A method to deserialize the game repository
/// </summary>
/// <param name="filename">A string representation of the input file name</param>
/// <returns>A SavedGameRepository object</returns>
public SavedGameRepository DeserializeRepository(string filename)
{
SavedGameRepository savedGameRepository = new SavedGameRepository();
using (Stream stream = File.Open(filename, FileMode.OpenOrCreate))
{
BinaryFormatter bFormatter = new BinaryFormatter();
if (stream.Length > 0)
{
savedGameRepository = (SavedGameRepository)bFormatter.Deserialize(stream);
}
}
return savedGameRepository;
}
当然,问题在于数据文件仍然显示与数独解决方案相关联的文本,因此用户可以阅读和作弊。我尝试使用非对称加密,但当然游戏对象列表太长。我使用对称加密,只要游戏没有关闭就可以使用。关闭并重新打开后,密钥消失,加密的数据文件无法重新打开。是否可以保留对称加密密钥?
答案 0 :(得分:0)
尝试将序列化对象保存在SQLite表中。数据库可以使用密码加密,而且非常简单,因为您不必编写任何代码来加密,只需在连接字符串中添加密码。
优点:您没有大量分散的文件,易于编码和读写表。 缺点:如果此文件损坏,则整个保存都将丢失。
答案 1 :(得分:0)
当然可以保持对称密钥 - 它就像任何其他数据一样。例如,您可以将其保存到文件中。但在这种情况下,用户显然会从文件中恢复密钥。
这是加密的基本属性。加密用任意数量的数据(明文)的机密性代替少量数据(密钥)的机密性。更多相关信息:http://blogs.msdn.com/b/ericlippert/archive/2011/09/27/keep-it-secret-keep-it-safe.aspx
因为您的游戏必须能够读取该文件,所以它必须能够访问执行该操作所需的所有信息。充其量,你正在寻找某种混淆。你必须问自己一个问题:你真的非常关心作弊吗?
答案 2 :(得分:-1)
是的,您可以加密和解密。我会给你一个示例代码。
您的加密类将是这样的
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.Text;
using System.IO;
namespace demo.encry
{
public class Crypto
{
public Crypto()
{
}
public String encrypto(string te, string ps,
string Salt = "Kosher", string HashAlgorithm = "SHA1",
int PasswordIterations = 2, string InitialVector = "OFRna73m*aze01xY",
int KeySize = 256)
{
if (string.IsNullOrEmpty(te))
return "";
byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
byte[] PlainTextBytes = Encoding.UTF8.GetBytes(te);
PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(ps, SaltValueBytes, HashAlgorithm, PasswordIterations);
byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
RijndaelManaged SymmetricKey = new RijndaelManaged();
SymmetricKey.Mode = CipherMode.CBC;
byte[] CipherTextBytes = null;
using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))
{
using (MemoryStream MemStream = new MemoryStream())
{
using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
{
CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
CryptoStream.FlushFinalBlock();
CipherTextBytes = MemStream.ToArray();
MemStream.Close();
CryptoStream.Close();
}
}
}
SymmetricKey.Clear();
return Convert.ToBase64String(CipherTextBytes);
}
public String decrypto(string ct, string ps,
string Salt = "Kosher", string HashAlgorithm = "SHA1",
int PasswordIterations = 2, string InitialVector = "OFRna73m*aze01xY",
int KeySize = 256)
{
if (string.IsNullOrEmpty(ct))
return "";
byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
byte[] CipherTextBytes = Convert.FromBase64String(ct);
PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(ps, SaltValueBytes, HashAlgorithm, PasswordIterations);
byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
RijndaelManaged SymmetricKey = new RijndaelManaged();
SymmetricKey.Mode = CipherMode.CBC;
byte[] PlainTextBytes = new byte[CipherTextBytes.Length];
int ByteCount = 0;
using (ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes))
{
using (MemoryStream MemStream = new MemoryStream(CipherTextBytes))
{
using (CryptoStream CryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read))
{
ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length);
MemStream.Close();
CryptoStream.Close();
}
}
}
SymmetricKey.Clear();
return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount);
}
}
}
所以加密一个String do
Crypto cs =new Crypto();
String originaltext="hello";
String password="password123";
/encrypting
String encryptedtext=cs.encrypto(originaltext, password);
//decrypting
String decryptedtext=cs.decrypto(encryptedtext, password);