[英]How can I encrypt a data file in C#?
我正在開發數獨游戲,並且列出了可以保存的數獨游戲。 我目前有以下序列化程序類來保存游戲:
/// <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;
}
當然,這樣做的問題是數據文件仍然顯示與數獨解決方案關聯的文本,因此用戶可以閱讀和作弊。 我嘗試使用非對稱加密,但是當然游戲對象列表太長。 我使用了對稱加密,只要游戲沒有關閉,它就可以工作。 一旦關閉並重新打開,密鑰就消失了,無法重新打開加密的數據文件。 是否可以保留對稱加密密鑰?
嘗試將序列化的對象保存在SQLite表中。 可以使用密碼對數據庫進行加密,這非常簡單,因為您無需編寫任何代碼即可加密,只需在連接字符串中添加密碼即可。
優點:您沒有很多分散的文件,易於編碼和讀寫表。 缺點:如果此文件損壞,您的整個保存都將丟失。
當然,對稱密鑰可以保留-就像任何其他數據一樣。 您可以將其保存到例如文件中。 但是在這種情況下,用戶顯然會從文件中恢復密鑰。
這是加密的基本屬性。 加密將少量數據(密鑰)的機密性替換為任意數量的數據(明文)的機密性。 有關此的更多信息: http : //blogs.msdn.com/b/ericlippert/archive/2011/09/27/keep-it-secret-keep-it-safe.aspx
因為您的游戲必須能夠讀取文件,所以它必須能夠訪問執行此操作所需的所有信息。 充其量,您正在尋找某種混淆。 您必須問自己一個問題:您真的很在乎作弊嗎?
是的,您當然可以加密和解密。 我會給你一個示例代碼。
您的加密類將如下所示
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.