我正在开发数独游戏,我有一个可以保存的数独游戏列表。我目前有以下序列化程序类来保存游戏:
/// <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;
}当然,这样做的问题是,数据文件仍然显示与数独解决方案相关联的文本,因此用户可以阅读和作弊。我尝试使用非对称加密,但是游戏对象的列表当然太长了。我使用对称加密,只要游戏没有结束,它就可以工作。一旦关闭并重新打开,密钥就会消失,加密的数据文件将无法重新打开。是否可以持久化对称加密密钥?
发布于 2013-06-29 12:33:48
是的,你当然可以加密和解密。我会给你一个示例代码。
您的加密类将如下所示
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);
}
}
}所以要加密一个字符串
Crypto cs =new Crypto();
String originaltext="hello";
String password="password123";
/encrypting
String encryptedtext=cs.encrypto(originaltext, password);
//decrypting
String decryptedtext=cs.decrypto(encryptedtext, password);发布于 2013-06-29 12:50:57
尝试将序列化的对象保存在SQLite表中。数据库可以使用密码进行加密,而且它非常简单,因为您不需要编写任何代码来加密,只需在连接字符串中添加密码即可。
优点:你没有太多分散的文件,易于编码和读写到表中。缺点:如果此文件损坏,您的整个保存将丢失。
发布于 2013-06-30 00:09:03
当然,对称密钥可以持久化-它就像任何其他数据一样。例如,您可以将其保存到一个文件中。但是在这种情况下,用户显然会从文件中恢复密钥。
这是加密的一个基本属性。加密将任意数量数据(明文)的机密性替换为少量数据(密钥)的机密性。更多信息:http://blogs.msdn.com/b/ericlippert/archive/2011/09/27/keep-it-secret-keep-it-safe.aspx
因为您的游戏必须能够读取文件,所以它必须能够访问执行此操作所需的所有信息。在最好的情况下,您看到的是某种混淆。你必须问自己这个问题:你真的那么在意作弊吗?
https://stackoverflow.com/questions/17376575
复制相似问题