我想考虑一下数据的完整性。我有一个要序列化到db中的对象。一旦它被序列化,我将获取它的散列,并将其与数据一起存储为DB中的一个单独列。
然后,当我从db获得数据时,我可以检查哈希,如果哈希匹配,则反序列化数据。
这是有意义的,还是我只是在浪费CPU?是否有其他方法存储序列化对象,然后在数据库中验证数据未被篡改。存储数据的程序可能与读取数据的程序不相同。
我的具体示例是创建一个EmailMessage对象(因为System.Net.Mail.MailMessage不能序列化),序列化它并创建哈希。两者都存储在数据库中。稍后,我可以使用序列化的EmailMessage和哈希。我检索EmailMessage并创建另一个哈希。如果原始哈希与新哈希相同,则填充MailMessage对象并发送它。否则,创建一个TamperedWithException()。
下面的代码是我用来做哈希的代码。我正在使用json.net进行序列化。
public static class MD5HashHelper
{
    public static string CreateHash(string str)
    {
        string hash;
        using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
        {
            hash = BitConverter.ToString(
              md5.ComputeHash(Encoding.UTF8.GetBytes(str))
            ).Replace("-", String.Empty);
        }
        return hash;
    }
    public static bool CompareWithHash(this string str, string hash)
    {
        string strHash = CreateHash(str);
        return strHash.Equals(hash,StringComparison.Ordinal);
    }
}这个特定的表尚未加密。攻击者可以进行更改并创建另一个哈希。这就是为什么我认为可能有更好的方法来做到这一点。
以下是序列化:
public static class JSONHelper
{
    public static string ToJSON(this object obj)
    {
        string json = JsonConvert.SerializeObject(obj);
        return json;
    }
    public static T JSONToObject<T>(this string json)
    {
        Object obj = JsonConvert.DeserializeObject<T>(json);
        return (T)Convert.ChangeType(obj, typeof(T));
    }
}发布于 2016-11-07 19:28:08
只要盐是保密的,盐就会有帮助。但这是一个问题,因为它也必须对合法签名者可用,因此可能对攻击者可用。是哈希盐根本不需要麻烦的哈希。我的攻击:读取数据,进行更改,创建新的哈希,保存修改后的数据并返回到DB。
这样的攻击是有解决方案的,但是你必须定义你所保护的东西的价值,以及你要保护的对象。当数据不能同时使用时,散列通常适用于数据。例如,苹果在一个频道上提供他们的更新,并将哈希发送到他们的安全电子邮件列表,一个单独的频道。
在没有严格的访问限制和硬件(如HSM)的情况下,试图保护所有攻击者是不可能的。即便如此,也有一些国家拥有庞大的预算,而且最终还拥有胶管密码分析。
发布于 2016-11-07 21:48:42
如果我没猜错你的情况,你担心有人会:
在这种情况下,最可怕的事情是攻击者只需要访问一个单一的系统,数据库,欺骗反篡改机制。
第一个不那么容易的尝试是在应用程序系统中添加一个“秘密密钥”:在您的代码中,您可以在要散列的字符串中添加一个固定前缀(salt),这样攻击者就需要访问数据库和这些“机密”信息来篡改数据。
但是,正如@zaph明确强调的那样,这是尽可能强大的,因为它可以对攻击者保密(已经能够访问您的数据库)。
更糟糕的是,这种“盐”不仅在写入数据的应用程序中是必要的,而且还应该与读取数据的应用程序共享,因为您建议
存储数据的程序可能与读取数据的程序不相同。
如果我们想进一步复杂化这个方案,我们可以使用一个“公钥”系统:在用“写入应用程序”私钥存储它之前先对MD5进行加密,这样“读取应用程序”就可以读取它并验证消息对象,而不需要伪造新的哈希。
...but,说真的,你最好从其他人那里得到安全建议,而不是我在StackOverflow :-)
https://stackoverflow.com/questions/40471918
复制相似问题