使用同一对象生成校验和时已更改

时间:2018-09-11 14:23:36

标签: c# .net sha256

我有一种算法可以用来在调用更新操作时生成并返回一个checkSum。第二次更新需要发送给定的校验和,以证明对象完全相同。否则,将引发异常。

这是我用来管理校验和的课程:

public class TokenUpdate
{
    internal readonly DateTime expireDateTime;
    private static readonly Object locker = new Object();
    internal readonly byte[] _dataTokenKey;

    public TokenUpdate(object insuranceAgreement, DateTime newExpireDateTime)
    {
        expireDateTime = newExpireDateTime;
        _dataTokenKey = GetSignedToken(insuranceAgreement);

    }

    public TokenUpdate(byte[] dataTokenKey, DateTime newExpireDateTime)
    {
        expireDateTime = newExpireDateTime;
        _dataTokenKey = dataTokenKey;

    }
    public bool IsExpired
    {
        get
        {
            return !(expireDateTime > DateTime.Now);
        }
    }

    public byte[] GetSignedToken(object insuranceAgreement)
    {
        byte[] tokenKey;

        byte[] tokenData;

        // serialize data in byte[]
        using (var ms = new MemoryStream())
        {
            using (var writer = new BinaryWriter(ms))
            {
                writer.Write(ObjectToByteArray(insuranceAgreement));
                tokenData = ms.ToArray();
            }
        }


        using (var sha1 = new SHA256Managed())
        {
            tokenKey = sha1.ComputeHash(tokenData);
        }


        return tokenKey;
    }

    public string GetTokenString()
    {
        byte[] tokenData;

        // serialize data in byte[]
        using (var ms = new MemoryStream())
        {
            using (var writer = new BinaryWriter(ms))
            {
                writer.Write(expireDateTime.Ticks);
                tokenData = ms.ToArray();
            }
        }


        return Convert.ToBase64String(tokenData.Concat(_dataTokenKey).ToArray());
    }

    public static TokenUpdate BuildToken(object insuranceAgreement, DateTime expireDateTime)
    {
        if (insuranceAgreement == null)
        {
            return null;
        }

        return new TokenUpdate(insuranceAgreement, expireDateTime);
    }

    public static bool AreEqual(TokenUpdate token, object toCompare)
    {
        var compareToken = new TokenUpdate(toCompare, DateTime.Now);


        return token._dataTokenKey.SequenceEqual(compareToken._dataTokenKey);
    }

    public static TokenUpdate GetTokenFromString(string tokenString)
    {
        TokenUpdate returnedToken = null;
        byte[] buffer;
        try
        {
            buffer = Convert.FromBase64String(tokenString);
        }
        catch (FormatException)
        {
            return null;
        }

        if (buffer.Length != 40)
        {
            return null;
        }

        var data = buffer.Take(buffer.Length - 32).ToArray();
        var sig = buffer.Skip(data.Length).Take(32).ToArray();
        using (var ms = new MemoryStream(data))
        using (var reader = new BinaryReader(ms))
        {
            var ticks = reader.ReadInt64();
            var expires = new DateTime(ticks);
            returnedToken = new TokenUpdate(sig, expires);
        }

        return returnedToken;
    }

    internal static byte[] ObjectToByteArray(object objectToSerialize)
    {
        if (objectToSerialize == null)
        {
            return null;
        }

        MemoryStream fs = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();
        try
        {
            //Here's the core functionality! One Line!
            //To be thread-safe we lock the object
            lock (locker)
            {
                formatter.Serialize(fs, objectToSerialize);
            }
            return fs.ToArray();
        }
        catch (SerializationException se)
        {
            throw;
        }
        finally
        {
            fs.Close();
        }
    }
}

通过一些单元测试,一切都很好,但是运行一些压力测试表明,在30%的情况下,第二次更新被拒绝,因为将校验和与从数据库中数据生成的校验和进行比较的比较失败

我检查了一下,几乎可以确定其他两个之间没有内部更新。

我想知道,与SHA256Managed类相关的哈希算法是否与系统datetime的mac地址相关? 因为我们负载均衡,所以可能会导致问题。

0 个答案:

没有答案