c# - JavaScript 中的 SHA256Cng

标签 c# java javascript hash sha256

我需要能够在 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代码,这可能会解决这个问题。

顺便说一句,此代码是一个简单的移动应用程序(html 基础)的一部分,该应用程序将使用 PhoneGap 发布。服务器上没有可用于生成哈希值的 API。

最佳答案

哈希部分实际上工作正常 - 在这两种情况下您都得到相同的二进制数据 - 唯一的区别是 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>

...一切都应该没问题。 (当然,请检查您是否拥有该文件...)

关于c# - JavaScript 中的 SHA256Cng,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23380851/

相关文章:

c# 将位图保存到文件,保存目录错误?

javascript - 断言两个二维数组是否相等

java - 如何在 Safari 中通过 Javascript 访问 Java 对象

c# - 复制注册表中的子类别

c# - 从数据库中过滤 MVC SelectList

java - 根据类别拆分数组列表的最佳方法

java - 如何在 spring-mvc 中将子类传递给 Controller ​​?

java - 多个 Activity 和按钮?

javascript - 从 jQuery 对象获取值数组

c# - 在 SEO 的动态 UR 中使用 *.html 扩展名