Reimplement ASP.NET Membership and User Password Hashing in Ruby

前端 未结 4 1064
-上瘾入骨i
-上瘾入骨i 2020-12-05 12:11

I have a large database of users (~200,000) that I\'m transferring from a ASP.NET application to a Ruby on Rails application. I don\'t really want to ask every user to rese

相关标签:
4条回答
  • 2020-12-05 12:40

    I have been tasked with migrating an existing .NET app to Ruby on Rails. I am using the code below to mimic the .NET password hashing. I am very new to Ruby, and don't know .NET at all. The code may not be as clean as it could, but it's a start.

    To test, save this as a Ruby script and run with:

    ruby script plain_text_password salt_in_base64

    e.g.

    ruby dotNetHash.rb password123 LU7hUk4MXAvlq6DksvP9SQ==

    require "base64"
    require "digest"
    
    # Encode password as double-width characters
    password_as_text = ARGV.first
    double_width_password = []
    double_width_password = password_as_text.encode("UTF-16LE").bytes.to_a
    
    # Unencode the salt
    salt = Base64.decode64(ARGV[1])
    
    # Concatenate salt+pass
    salt_pass_array = []
    salt_pass_array = salt.bytes.to_a + double_width_password
    
    # Repack array as string and hash it. Then encode.
    salt_pass_str = salt_pass_array.pack('C*')
    sha1_saltpass = Digest::SHA1.digest(salt_pass_str)
    enc_sha1_saltpass = Base64.encode64(sha1_saltpass).strip()
    puts "Encoded SHA1 saltpass is " + enc_sha1_saltpass
    
    0 讨论(0)
  • 2020-12-05 12:42

    Just a quick update, a colleague of mine has solved this:

    require "base64"
    require "digest"
    require "jcode"
    
    
    def encode_password(password, salt)
     bytes = ""
     password.each_char { |c| bytes += c + "\x00" }
     salty = Base64.decode64(salt)
     concat = salty+bytes
     sha1 = Digest::SHA1.digest(concat)
     encoded = Base64.encode64(sha1).strip()
     puts encoded
    end
    
    0 讨论(0)
  • 2020-12-05 12:43

    You are pretty close. Unfortunately Ruby has no built-in unicode support at the moment, and your hashing function relies on it. There are workarounds. Look around the site on how to do unicode in Ruby. BTW, I think you forgot to base64 decode the salt, it looks like the ASP.net function does that.

    0 讨论(0)
  • 2020-12-05 12:54

    You need to unencode the salt to convert it back to it's byte representation and then concatenate that with the password to get the hashed password value. You're using the encoding salt string directly (which is a different salt) and thus it is hashing to something different.

    require "base64"
    require "digest/sha1"
    password = "password"
    salt = Base64.decode64("1ptFxHq7ALe7yXIQDdzQ9Q==")
    concat = salt+password
    sha1 = Digest::SHA1.digest(concat)
    encoded = Base64.encode64(sha1)
    puts encoded
    
    0 讨论(0)
提交回复
热议问题