Chrome和IE返回不同的SHA哈希值

时间:2014-06-11 04:51:28

标签: javascript c# google-chrome internet-explorer asp.net-web-api2

我写了一个利用SHA-256哈希来验证用户密码的网站。这是一个相对不安全的设置,因为大多数用户将拥有相同的用户名/密码。为了尝试保护它至少一点点,我做了以下几点:

  1. 客户端从服务器请求新的盐
  2. 客户端使用此盐哈希密码
  3. 客户端将带有salt的哈希密码发送回服务器
  4. 服务器哈希实际密码并比较两个
  5. 这是我的代码:

    C#

    //Just for testing!
    private static Dictionary<string, string> users = new Dictionary<string, string>() { { "User", "Password" } };
    
    [HttpGet]
    public HttpResponseMessage GetSalt()
    {
       RNGCryptoServiceProvider secureRNG = new RNGCryptoServiceProvider();
       byte[] saltData = new byte[64];
    
       secureRNG.GetBytes(saltData);
    
       HttpResponseMessage response = new HttpResponseMessage();
       response.Content = new StringContent(System.Text.Encoding.Unicode.GetString(saltData), System.Text.Encoding.Unicode);
       return response;
    }
    
    [HttpGet]
    public bool ValidateUser(string userName, string hashedPassword, string salt)
    {
       SHA256Managed hash = new SHA256Managed();         
       if (users.ContainsKey(userName))
       {
           string fullPassword = salt + users[userName];
           byte[] correctHash = hash.ComputeHash(System.Text.Encoding.UTF8.GetBytes(fullPassword));
    
           if (hashedPassword.ToUpper() == BitConverter.ToString(correctHash).Replace("-",""))
           {
               return true;
           }
       }
       return false;
    }
    

    的Javascript

    $scope.login = function () {
        $http.get('api/Login').success(function (salt) {
            //Hash the password with the salt and validate
            var hashedPassword = sjcl.hash.sha256.hash(salt.toString().concat($scope.password));
            var hashString = sjcl.codec.hex.fromBits(hashedPassword);
    
            $http.get('api/Login?userName=' + $scope.userName + '&hashedPassword=' + hashString + '&salt=' + salt).success(function (validated) {
                $scope.loggedIn = validated;
            });
        });
    

    此代码在Google Chrome上运行正常,但在Internet Explorer 11上运行不正常。问题(如调试器中所示)是由javascript生成的哈希与C#生成的哈希不同。

    怀疑这与字符编码有关,但是在网上找不到太多证据来证明/反驳这个理论(或者总体上帮助解决这个问题)。如果有更好的方法来解决这个问题,我很高兴听到它,但也希望了解原始错误的原因。

    为什么哈希不同,我该怎么做才能解决?

1 个答案:

答案 0 :(得分:3)

IE在查询字符串中执行之类的Unicode字符。它也不像某些特殊的&#34; ASCII字符。即使它正确接受它们并正确执行哈希,当你运行这段代码时,盐就是&#34; ???????&#34;来自IE时,以及来自Chrome的正确字符串。

简单的解决方法是将salt的字符集限制为大写,小写和数字。使用此方法,两个浏览器都会提供正确的哈希值。