I need to check asp-generated passwords in php/Laravel. Could you help me to translate this asp code used to generate those passwords?
password = "xxx"
salt = "yyy"
saltedPassword = salt & password
Set objUnicode = CreateObject("System.Text.UnicodeEncoding")
arrByte = objUnicode.GetBytes_4(saltedPassword)
Set objSHA512 = Server.CreateObject("System.Security.Cryptography.SHA512Managed")
strHash = objSHA512.ComputeHash_2((arrByte))
'Ref: http://stackoverflow.com/questions/1118947/converting-binary-file-to-base64-string
Dim xml: Set xml = CreateObject("MSXML2.DOMDocument.3.0")
xml.LoadXml "<root />"
xml.documentElement.dataType = "bin.base64"
xml.documentElement.nodeTypedValue = strHash
ToBase64String = Replace(xml.documentElement.Text,VbLf, "")
Response.Write "<p>" & ToBase64String & "</p>"
I tried with this:
$password = 'xxx';
$salt = 'yyy';
$saltedpass = $salt.$password;
dd( base64_encode( hash('sha512', $saltedpass, true) ) );
but I get different strings.
Here's my go to ASP hashing function for anyone looking to do fast and simple hashing in Classic ASP. It allows you to hash as MD5, SHA1, SHA256, SHA384 and SHA512, as well as encode as Hex or Base64.
UPDATE I've also included an option to specify a character set too (Unicode or UTF8).
Function Hash(ByVal Input, HashAlgorithm, CharSet, Encoding)
' Select the System.Security.Cryptography value.
Select Case uCase(HashAlgorithm)
Case "MD5"
HashAlgorithm = "MD5CryptoServiceProvider"
Case "SHA1"
HashAlgorithm = "SHA1CryptoServiceProvider"
Case "SHA2","SHA256"
HashAlgorithm = "SHA256Managed"
Case "SHA384"
HashAlgorithm = "SHA384Managed"
Case "SHA5","SHA512"
HashAlgorithm = "SHA512Managed"
Case Else
HashAlgorithm = "SHA1CryptoServiceProvider"
End Select
' Convert the input to bytes if not already.
If NOT VarType(Input) = 8209 Then
Dim CS : Set CS = Server.CreateObject("System.Text." & CharSet & "Encoding")
Input = CS.GetBytes_4(Input)
Set CS = Nothing
End If
' Perform the hash.
Dim hAlg : Set hAlg = Server.CreateObject("System.Security.Cryptography." & HashAlgorithm)
Dim hEnc : Set hEnc = Server.CreateObject("MSXML2.DomDocument").CreateElement("encode")
Encoding = lCase(Encoding)
If Encoding = "base64" OR Encoding = "b64" Then
hEnc.dataType = "bin.base64"
Else
hEnc.dataType = "bin.hex"
End If
hEnc.nodeTypedValue = hAlg.ComputeHash_2((Input))
Hash = hEnc.Text
Hash = Replace(Hash,VBlf,"")
Set hEnc = Nothing
Set hAlg = Nothing
End Function
Dim password, salt, saltedPassword
password = "xxx"
salt = "yyy"
saltedPassword = salt & password
Response.Write(Hash(saltedPassword,"SHA512","Unicode","Base64"))
In this example, I've set it to match your code, so it's using System.Text.UnicodeEncoding
to get the bytes (although UTF8 should be used by default, it's why your PHP code was returning a different Base64 string), and Hash = Replace(Hash,VBlf,"")
is needed as bin.base64
almost always includes a line feed, but PHP never does. This is the Base64 output:
RLW8OiWU7AN3zhc3Avo7u7OOMjUybf8p8R98dafTPJJPCwfKbxd7soEEZlpXU4CmJ2a4HpGhnLPQFf7at1+yxA==
...which matches the Base64 output generated by your ASP code.
Now to achieve the same in PHP, simply use mb_convert_encoding
with UTF-16LE
when joining the salt and password:
$password = 'xxx';
$salt = 'yyy';
$saltedpass = mb_convert_encoding($salt.$password,'UTF-16LE');
echo(base64_encode(hash('sha512',$saltedpass,true)));
The PHP hash
function will behave the same as using System.Text.UnicodeEncoding
in Classic ASP. I don't have Laravel installed, so I could only test using echo
, print
or var_dump
, but not dd
, here's the Base64 output in PHP:
RLW8OiWU7AN3zhc3Avo7u7OOMjUybf8p8R98dafTPJJPCwfKbxd7soEEZlpXU4CmJ2a4HpGhnLPQFf7at1+yxA==
They're an exact match.