弹力城堡HMAC SHA1

时间:2019-08-15 07:55:54

标签: c# bouncycastle hmac hmacsha1

我有以下代码使用BouncyCastle(dotnet版本)从消息中获取HMAC-SHA1。

我有这个小图书馆课:

This Is Output
-
This Is Error

我通过此方法有很多消息,所有消息都使用相同的密钥:public class HashingTools { static string hmacKey = "81310910a060c5705c1d3cedf370bcf9"; public static int HashSizeInBytes = 20; static KeyParameter keyParameter = null; private static HMac hmacInstance; static HashingTools() { hmacInstance = new HMac(new Sha1Digest()); hmacInstance.Init(newKeyParameter(Encoding.UTF8.GetBytes(hmacKey))); } public static byte[] HashSha1(byte[] message) { byte[] result = new byte[hmacInstance.GetMacSize()]; hmacInstance.BlockUpdate(message, 0, message.Length); hmacInstance.DoFinal(result, 0); return result; } } ,并且我想尽可能地加快速度,并尽可能地重复使用关于安全性参数(随机性,新鲜度...)。

如果我尝试重用或并行化hmacKey实例,则会在hmac内收到“数组越界”异常。

我已经创建了用于复制的单元测试(1或2个并行散列函数可以正常运行,而100个则可以出错):

Org.BouncyCastle.Crypto.Macs.Hmac.BlockUpdate

1 个答案:

答案 0 :(得分:1)

@dlatikay正确推测,这是一个同步错误。 Bouncycastle的类不是线程安全的,除非他们明确声明是安全的。

如果您修改HashSha1方法以显式同步线程,则不会出现异常:

public static byte[] HashSha1(byte[] message) {
    byte[] result = new byte[hmacInstance.GetMacSize()];
    lock(hmacInstance) {
        hmacInstance.BlockUpdate(message, 0, message.Length);
        hmacInstance.DoFinal(result, 0);
    }

    return result;
}

关于您的优化问题,Bouncycastle已经预先计算了涉及密钥的计算部分。调用DoFinal(...)时,内部状态将重置为该预先计算的值,因此,如果您使用相同的密钥,则无需为下一个HMac再次调用Init()。您的代码已经利用了这种优化,因此除非您想编写自己的哈希代码,否则我认为您不能做更多的事情。