更新TextBox时更新DataTable中的字段

时间:2017-06-01 15:51:12

标签: c# datatable passwords password-protection in-memory

当用户更改数据时,我需要在C#app中更新DataTable中的字段。

DataTable是一个内存中的DataTable - 我将任何数据保存并加载到XML文件(writeXML方法),因此没有底层数据库。 我使用它来保存有关登录的一些信息,因此我有一个我想要加密的密码字段。这很重要,因为当我将保存运行到XML时,它会以非加密方式写出密码。

我正在考虑采用这两种不同的方式,并希望得到一些反馈。

  1. 从XML加载,然后解密每行中的所有密码值,并在保存到XML之前加密它们。我可以使用类似的东西:

    foreach (DataRow row in tmp.Rows)
    {
        row["PW"] = EncryptIt(row["PW"].ToString());
    }
    

    然而,这似乎有点不安全。它会给我一个内存中的DataTable,它有密码解密。但我认为使用时一次解密一个密码没有什么不同......

  2. 保持内存中DataTable的密码加密。但是当用户使用屏幕编辑记录时,我可以在用户输入后加密TextBox中输入的值。然后,每当我需要使用它时,我也可以解密DataTable中的值。这会将密码保存在DataTable中,但是当我需要使用它们时我必须解密它们,所以我不确定它是否真的比上面更简单的方法更安全。

  3. 您对上述方法1对2有什么看法?

    上面的方法#2还介绍了一些关于如何最好地加密数据的其他问题 - 我的意思是使用什么事件?

    我一直在玩EditValueChangedTextChanged,但他们似乎都会为每个被改变的角色开火。我还需要考虑各种情况,例如离开现场,而不是在用户更改字段的情况下离开字段,然后只需点击“保存”按钮而不离开字段。

    当用户将数据绑定更改为该字段(通过绑定源)时,您将如何更新基础DataTable字段?

    我开始认为选项一更易于实施,而且在安全性方面也没有变得更糟。或者我错过了什么?

2 个答案:

答案 0 :(得分:0)

如果你担心记忆中的明文,你建议我选择2种方法。 您还可以考虑在数据库中散列密码。散列是一种单向加密,您始终比较“加密”结果,并且无法检索原始密码。

有一篇关于哈希的好文章here

第二部分广告,当用户点击保存按钮时,编辑字段首先失去焦点,因此如果您订阅了文本框的leave事件,那么您应该是安全的。

答案 1 :(得分:0)

我打算发表评论,但我认为回复会更好,因为我发送了一些示例代码。

处理密码存储的一个更好的方法是生成一个salt,然后使用它来散列密码,然后在数据库中存储salt和散列传递。当用户登录时,您获取salt,使用它对其输入进行散列,然后与数据库中的散列进行比较。

    public static string CreateSalt(int size)
    {
        // Generate a cryptographic random number using the cryptographic
        // service provider
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        byte[] buff = new byte[size];
        rng.GetBytes(buff);
        // Return a Base64 string representation of the random number
        return Convert.ToBase64String(buff);
    }

    public static string CreatePasswordHash(string pwd, string salt)
    {
        string saltAndPwd = String.Concat(pwd, salt);
        string hashedPwd =
              FormsAuthentication.HashPasswordForStoringInConfigFile(
                                                   saltAndPwd, "SHA1");
        hashedPwd = String.Concat(hashedPwd, salt);
        return hashedPwd;
    }

这些是你需要的两个助手。 要创建散列密码(对于新用户),您可以执行以下操作:

var salt = CreateSalt(24);
var passHash = CreatePasswordHash(password, salt);

再次,在数据库中存储salt和散列传递。

检查登录时,向数据库询问盐和散列传递。 像以前一样散列密码,然后与散列传递进行比较。

更好,更安全的是,在数据库中创建一个存储过程,如果散列传递与表中的传递相同则返回 - 然后哈希传递甚至永远不会下载到客户端,只有盐

应该注意的是,根据https://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.hashpasswordforstoringinconfigfile(v=vs.110).aspxFormsAuthentication.HashPasswordForStoringInConfigFile方法已经过时了,您应该查看http://go.microsoft.com/fwlink/?LinkId=252463但是,我没有示例代码(我可以考虑到...)。当然,如果您使用的是桌面/ Windows窗体应用程序,那对您没有帮助,但重点是:

使用salt哈希密码。 永远不要解密存储的密码。