使用BouncyCastle生成HMAC-SHA256散列

时间:2021-03-06 18:22:58

I need to generate a HMAC-SHA256 hash in a PCL (developing for Xamarin Forms) which doesn't support the .NET built-in HMAC/cryptography classes, so I'm working with BouncyCastle to implement my cryptography classes.

我需要在PCL中生成一个HMAC- sha256散列(为Xamarin格式开发),它不支持. net内置的HMAC/加密类,因此我正在使用BouncyCastle实现我的加密类。

I need to generate a HMAC-SHA256 hash, but I haven't been able to find any example on Google, nor does BouncyCastle seem to have any documentation for this. Can anyone help me out?

我需要生成一个HMAC-SHA256散列,但是我还没有在谷歌上找到任何示例,BouncyCastle似乎也没有任何相关的文档。谁能帮我一下吗?

3 个解决方案

#1


6  

Thanks to the solution here I came up with this code:

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

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;
    }
}

Corresponding unit test (uses FluentAssertions):

对应的单元测试(使用fluentassert):

[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);
    }
}

#2


1  

Using this PCL offshoot of BouncyCastle https://www.nuget.org/packages/BouncyCastle-PCL/1.0.0.6 it's really easy, in fact identical to the windows api.

使用这个PCL的BouncyCastle分支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);
    }

And a unit test using the actual .Net version:

以及使用。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));
    }

I was using PCLCrypto but it kept crashing on Xamarin iOS, this was much cleaner and could be unit tested, wheras PCLCrypto required the platform apis so had to be deployed to a device.

我当时使用的是PCLCrypto,但它在Xamarin iOS上一直在崩溃,它更干净,可以进行单元测试,而PCLCrypto需要将平台api部署到设备上。

#3


0  

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);
    }

Above code saved my time while working for HMAC-SHA256, I hope this may help someone and here is the reference in detail http://billatnapier.com/security01.aspx

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

#1


6  

Thanks to the solution here I came up with this code:

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

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;
    }
}

Corresponding unit test (uses FluentAssertions):

对应的单元测试(使用fluentassert):

[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);
    }
}

#2


1  

Using this PCL offshoot of BouncyCastle https://www.nuget.org/packages/BouncyCastle-PCL/1.0.0.6 it's really easy, in fact identical to the windows api.

使用这个PCL的BouncyCastle分支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);
    }

And a unit test using the actual .Net version:

以及使用。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));
    }

I was using PCLCrypto but it kept crashing on Xamarin iOS, this was much cleaner and could be unit tested, wheras PCLCrypto required the platform apis so had to be deployed to a device.

我当时使用的是PCLCrypto,但它在Xamarin iOS上一直在崩溃,它更干净,可以进行单元测试,而PCLCrypto需要将平台api部署到设备上。

#3


0  

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);
    }

Above code saved my time while working for HMAC-SHA256, I hope this may help someone and here is the reference in detail http://billatnapier.com/security01.aspx

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