首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在C#中加密数据文件?

如何在C#中加密数据文件?
EN

Stack Overflow用户
提问于 2013-06-29 12:02:48
回答 3查看 530关注 0票数 0

我正在开发数独游戏,我有一个可以保存的数独游戏列表。我目前有以下序列化程序类来保存游戏:

代码语言:javascript
运行
复制
    /// <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;
    }

当然,这样做的问题是,数据文件仍然显示与数独解决方案相关联的文本,因此用户可以阅读和作弊。我尝试使用非对称加密,但是游戏对象的列表当然太长了。我使用对称加密,只要游戏没有结束,它就可以工作。一旦关闭并重新打开,密钥就会消失,加密的数据文件将无法重新打开。是否可以持久化对称加密密钥?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-29 12:33:48

是的,你当然可以加密和解密。我会给你一个示例代码。

您的加密类将如下所示

代码语言:javascript
运行
复制
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);
        }
    }

}

所以要加密一个字符串

代码语言:javascript
运行
复制
Crypto cs =new Crypto();
String originaltext="hello";
String password="password123";
/encrypting
String encryptedtext=cs.encrypto(originaltext, password);
//decrypting
String decryptedtext=cs.decrypto(encryptedtext, password);
票数 -1
EN

Stack Overflow用户

发布于 2013-06-29 12:50:57

尝试将序列化的对象保存在SQLite表中。数据库可以使用密码进行加密,而且它非常简单,因为您不需要编写任何代码来加密,只需在连接字符串中添加密码即可。

优点:你没有太多分散的文件,易于编码和读写到表中。缺点:如果此文件损坏,您的整个保存将丢失。

票数 0
EN

Stack Overflow用户

发布于 2013-06-30 00:09:03

当然,对称密钥可以持久化-它就像任何其他数据一样。例如,您可以将其保存到一个文件中。但是在这种情况下,用户显然会从文件中恢复密钥。

这是加密的一个基本属性。加密将任意数量数据(明文)的机密性替换为少量数据(密钥)的机密性。更多信息:http://blogs.msdn.com/b/ericlippert/archive/2011/09/27/keep-it-secret-keep-it-safe.aspx

因为您的游戏必须能够读取文件,所以它必须能够访问执行此操作所需的所有信息。在最好的情况下,您看到的是某种混淆。你必须问自己这个问题:你真的那么在意作弊吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17376575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档