4
votes

I'm trying to compile a software written in VB (I'm using VisualStudio2010, Framework 4) that lets users change their passwords on a website (sadly the website default changepassword form doesn't work, and I can't fix that via PHP).

I don't have much experience with PHP and encrypting, so I looked on the internet for some solutions for VB.Net, but didn't get the expected results after 2 days of trying.

I did some research, and that's what I learned: Website's PHP code uses the crypt($string,$salt) function to create the hashed password. The encoding is a MD5 algorithm, as my salt is something like '$1$ad000000$' for every password in website's database.

I tried to replicate it in VB and the issues start on the ComputeHash(buffer() as Byte), as it doesn't support a "Salt" String.

The code on PHP is as simple as that:

$EncryptedPassword = crypt($userPassword, $salt);

The salt is generated to look like, for example, "$1$ad000000$"

The $EncryptedPassword length is 34 (12salt + 22hash), but I guess this is a standard length of the crypt() function, given a specific salt.

This is what I'm currently trying on VB:

Dim Hashata = GetHash("asdkFAofkas", "$1$ad000000$")

Private Function GetHash(ByVal p1 As String, ByVal Salt As String) As Object
        Using hasher As MD5 = MD5.Create()
            Dim dbytes As Byte() = hasher.ComputeHash(Encoding.UTF8.GetBytes(p1 & Salt))
            Dim Conversione = Convert.ToBase64String(dbytes)
            Return Conversione
        End Using
    End Function

The return string is a 24-character string always ending with "==" no matter what "p1" is, and I read on the internet that these last two characters are optional, so when creating the password-hash with Salt, I just do:

Dim StoredPassword = Salt & Hashata.Substring(0,Hashata.Length-2)

The created StoredPassword (VB) doesn't coincide with the password (PHP) in the DataBase when I write the same Password. I tried this with creating multiple users on the website with the same Password, and they are all hashed in the same way in the Database.

For example, this is what I have in the Database:

-------------------------------------------------
| Username | Password                           |
-------------------------------------------------
|test1     |$1$ad000000$kcpPLtMxsedGD0d39UnXQg  |
-------------------------------------------------
|test2     |$1$ad000000$kcpPLtMxsedGD0d39UnXQg  |
-------------------------------------------------
|test3     |$1$ad000000$kcpPLtMxsedGD0d39UnXQg  |
-------------------------------------------------
|testVB    |$1$ad000000$5u-9pdu3HDnXt5pGdXZNug  |
-------------------------------------------------

test1,test2,test3 have passwords made on website

testVB has a password generated by VB's function above

I wrote the exact same password for test1,test2,test3 and testVB.

ALL passwords on the database have a length of 34 characters

I already tried the following (on VB, as I can't modify website's PHP):

  • Encode only p1, only Salt, both variables mixed (like in the code above)

  • Convert p1 and Salt to a hex string (first only one, then only the other one, then both, etc...) before encoding them singularly or while mixing them

  • Use different types of Encoding (UTF-7, UTF-16, UTF-32, "Default" and ASCII)

I'm pretty sure the issue is on the ComputeHash Function, which doesn't have a "Salt" property (it has an offset and count properties, but I didn't use them), and without that, it can't crypt in the way I'd like.

Is there a way to replicate PHP's crypt($string, $salt) function?

I can bet that without the $salt they coincide (I already found some solutions that worked like that, but I need that $salt for crypting because I cannot modify website's PHP code to crypt without $salt).

Thanks a lot, sorry for the long read, I want to make sure I didn't miss anything :)

If there's something else I need to add, let me know!

1
A friend of mine, after I sent him the same question, told me that I can try to make a WebService written in PHP to call during the password generation in VB (that way I can crypt the password with PHP's crypt() function). I didn't even think about that option. I'll leave the question open, if anyone has an alternative answer, and I'll edit this question with some code as soon as I write it and make it work.AdrianLegolax
You don't want to create one with an explicit salt. Rather, let the library do it for you. Follow the documentation.Scott Arciszewski

1 Answers

0
votes

Bcrypt.NET gives you want you want.

string passwordHash = BCrypt.HashPassword("my password");
if (BCrypt.Verify("my password", passwordHash)) {
    // Valid
} else {
    // Incorrect password
}