ComputeHash は lock が必要

APIを呼びだすとき、SHA256で署名を追加したりします。
こんな感じのコードがありました。

static string SignWithHMACSHA256(string data, string secret)
{
    using (var encoder = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
    {
        var hash = encoder.ComputeHash(Encoding.UTF8.GetBytes(data));
        return ToHexString(hash);
    }
}

ただ、secretって、毎回変わることはないので、encoderは、事前に作って、staticで使いまわしができます。

static encoder = new HMACSHA256(Encoding.UTF8.GetBytes(secret);

static string SignWithHMACSHA256(string data)
{
    var hash = encoder.ComputeHash(Encoding.UTF8.GetBytes(data));
    return ToHexString(hash);
}

こんな感じに変えてみると、速くはなるのですが、たまにエラーを出すようになってしまいました。
HMACSHA256.ComputeHashって、スレッドセーフじゃないんですね。
で、こんな感じ

static encoder = new HMACSHA256(Encoding.UTF8.GetBytes(secret);

static string SignWithHMACSHA256(string data)
{
    byte[] hash;
    lock(encoder)
    {
        hash = encoder.ComputeHash(Encoding.UTF8.GetBytes(data));
    }
    return ToHexString(hash);
}

lockを入れても、毎回encoderをnewするよりは、かなり速くなります。

1件のコメント

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です