使用 BouncyCastle 生成 HMAC-SHA256 哈希



我需要在不支持.NET内置HMAC/加密类的PCL(为Xamarin Forms开发)中生成HMAC-SHA256哈希,所以我正在使用BouncyCastle来实现我的加密类。

我需要生成一个HMAC-SHA256哈希,但我无法在Google上找到任何示例,BouncyCastle似乎也没有任何文档。谁能帮我?

多亏了这里的解决方案,我想出了这段代码:

public class HmacSha256
{
    public byte[] Hash(string text, string key)
    {
        var hmac = new HMac(new Sha256Digest());
        hmac.Init(new KeyParameter(Encoding.UTF8.GetBytes(key)));
        byte[] result = new byte[hmac.GetMacSize()];
        byte[] bytes = Encoding.UTF8.GetBytes(text);
        hmac.BlockUpdate(bytes, 0, bytes.Length);
        hmac.DoFinal(result, 0);
        return result;
    }
}

相应的单元测试(使用FluentAssertions):

[TestClass]
public class HmacSha256Tests
{
    private readonly HmacSha256 _hmac = new HmacSha256();
    [TestMethod]
    public void Hash_GeneratesValidHash_ForInput()
    {
        // Arrange
        string input = "hello";
        string key = "test";
        string expected = "F151EA24BDA91A18E89B8BB5793EF324B2A02133CCE15A28A719ACBD2E58A986";
        // Act
        byte[] output = _hmac.Hash(input, key);
        string outputHex = BitConverter.ToString(output).Replace("-", "").ToUpper();
        // Assert
        expected.Should().Be(outputHex);
    }
}

使用BouncyCastle的这个PCL分支 https://www.nuget.org/packages/BouncyCastle-PCL/1.0.0.6 它真的很容易,实际上与Windows API相同。

 public string ComputeHMAC(string message)
    {
        var keyBytes = Encoding.UTF8.GetBytes(Constants.API_KEY);
        var messageBytes = Encoding.UTF8.GetBytes(message);
        var hmac = new HMACSHA256(keyBytes);
        byte[] result = hmac.ComputeHash(messageBytes);
        return Convert.ToBase64String(result);
    }

以及使用实际 .Net 版本的单元测试:

[Test, AutoMoqData]
    public void Hash_Algorithm_Correct (
        [NoAutoProperties] HashMacService sut,
        string message)
    {
        string expected;
        var key = Encoding.UTF8.GetBytes(Constants.API_KEY);
        using (var hmac = new HMACSHA256(key))
        {
            var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
            expected = Convert.ToBase64String(hash);
        }
        var result = sut.ComputeHMAC(message);
        Assert.That(result, Is.EqualTo(expected));
    }

我正在使用PCLCrypto,但它在Xamarin iOS上不断崩溃,这更干净并且可以进行单元测试,而PCLCrypto需要平台API,因此必须部署到设备上。

private static void CreateToken(string message, string key)
    {
        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        byte[]keyByte = encoding.GetBytes(key);

        HMACSHA256 hmacsha = new HMACSHA256(keyByte);
        byte[]messageBytes = encoding.GetBytes(message);
        byte[]hashmessage = hmacsha.ComputeHash(messageBytes);
        Console.WriteLine(ByteToString(hashmessage));
    }
    public static string ByteToString(byte[]buff) {
        string sbinary = "";
        for (int i = 0; i < buff.Length; i++) {
            sbinary += buff[i].ToString("X2"); // hex format
        }
        return (sbinary);
    }

上面的代码节省了我在为 HMAC-SHA256 工作时的时间,我希望这可能会对某人有所帮助,这里是详细参考 http://billatnapier.com/security01.aspx

最新更新