有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

c#SHA256Cng的Javascript版本

我需要能够在javascript中生成一个匹配服务器的哈希值

以下是示例输入:

string plaintext = "1398836885";
string salt = "8xTpd9gMxF22nBcotVChIH5ocxplLQzI3Ba7xXBkMyyOVVr6e5/mupqxFHYVQD0U77BEbQ9auMWglUK63PeqCX4eB8kzBoOEAr1nXqpT3jjNwdYPQPdRvwPjdI/357CP";

正确的哈希结果是:

ovsvdWYOUIXU+LAfIYtOf7N60v6Qap6qBgS3IVwBG6k=  

获取明文的代码是:

var now = ((long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString();  

以及生成正确哈希的代码:

用法:

var _hash = Hashbrowns.Hash(plaintext, salt);  

代码:

public static class Hashbrowns
{
    private const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";

    public static string Hash(string plaintext, string salt = null)
    {
        return Hashbrowns.Hash<SHA256Cng>(plaintext, salt);
    }

    public static string Hash<TAlgorithm>(string plaintext, string salt = null) where TAlgorithm : HashAlgorithm, new()
    {
        var algorithm = Activator.CreateInstance<TAlgorithm>();

        if (string.IsNullOrWhiteSpace(salt))
        {
            salt = Config.Salt;
        }

        var data = Encoding.UTF8.GetBytes(plaintext + salt);
        return Convert.ToBase64String(algorithm.ComputeHash(data));
    }

    public static string HashPassword(string value)
    {
        return Hash(value, Config.Salt + Config.Spice);
    }

    public static string RandomString(int length)
    {
        var random = new Random();
        return new string(
            Enumerable
                .Repeat(Hashbrowns.chars, length)
                .Select(o => o[random.Next(o.Length)])
                .ToArray()
            );
    }
}  

JAVASCRIPT部分
在我的javascript代码中,我使用Crypto Js获得SHA256:

<script type="text/javascript" src="plugin/CryptoJS v3.1.2/rollups/sha256.js"></script>  

Hash: function(){

    var o = "13988354648xTpd9gMxF22nBcotVChIH5ocxplLQzI3Ba7xXBkMyyOVVr6e5/mupqxFHYVQD0U77BEbQ9auMWglUK63PeqCX4eB8kzBoOEAr1nXqpT3jjNwdYPQPdRvwPjdI/357CP",
            hash256 = CryptoJS.SHA256(o),           
        ;

    console.log(hash256.toString(CryptoJS.enc.Base64)); 

}  

结果是:

a2fb2f75660e5085d4f8b01f218b4e7fb37ad2fe906a9eaa0604b7215c011ba9  

显然,它们不一样

幸运的是,有一个版本的JAVA代码可以产生相同的结果。我刚从外包开发者那里得到了这段代码,我告诉你们,我对JAVA不太熟悉

StringBuilder sb = new StringBuilder();

    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.reset();
    byte[] buffer = hash.getBytes("UTF-8");
    md.update(buffer);
    byte[] digest = md.digest();

    for (int i  = 0; i < digest.length; i++){
      sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
    }

    hashKey = Base64.encodeToString(digest, Base64.DEFAULT);

}

他们说他们能用这个代码得到正确的结果。如果这个代码可以转换成javascript代码,这个问题就可以解决了

顺便说一句,这段代码是将使用PhoneGap发布的简单移动应用程序(html库)的一部分。服务器上没有API可以用来生成哈希


共 (1) 个答案

  1. # 1 楼答案

    散列部分实际上运行良好——在这两种情况下,您得到的是相同的二进制数据——唯一的区别是Javascript中的输出是十六进制的,而不是base64。此C#代码:

    using System;
    
    class Test
    {
        static void Main()
        {
            string base64 = "ovsvdWYOUIXU+LAfIYtOf7N60v6Qap6qBgS3IVwBG6k=";
            byte[] rawData = Convert.FromBase64(base64);
            Console.WriteLine(BitConverter.ToString(rawData));
        }
    }
    

    。。。打印出:

    A2-FB-2F-75-66-0E-50-85-D4-F8-B0-1F-21-8B-4E-7F-B3-7A-D2-FE-90-6A-9E-AA-06-04-B7-21-5C-01-1B-A9
    

    这与Javascript输出、模数大小写和字节之间的“-”相同

    我刚刚用Crypto js尝试过这个,我认为问题在于你没有enc-base64.js组件,它不包括在汇总中。只需添加:

    <script type="text/javascript" src="plugin/CryptoJS v3.1.2/components/enc-base64.js"></script>
    

    。。。一切都会好起来的。(当然,你有那份文件……)