There's a following function written in VBA.NET which I'm trying convert to PHP. I'm primarly a PHP developer, and I have alsmost zero-knowledge in VB.
<%
Public Shared Function ComputeHash(ByVal Key As String) As String
Dim objSHA1 As New SHA1CryptoServiceProvider
objSHA1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(Key.ToCharArray))
Dim buffer() As Byte = objSHA1.Hash
Dim HashValue As String = System.Convert.ToBase64String(buffer)
Return HashValue
End Function
%>
I have tried searching for manuals and found some guidelances.
This is so far what I have converted to PHP myself:
function compute_hash($string){
return base64_encode(sha1($string));
}
Hovewer it doesn't produce the same result as VB's function ComputeHash(). Coudn't someone tell what I'm doing wrong?
Example of execution on both languages:
VBA.NET
string = "orange45877687459999SENTRYORD01154321"
ComputeHash(string) // Returns = WbwSWEBzPqgo9C4nZmGwHhd/FBQ=
PHP
$string = "orange45877687459999SENTRYORD01154321";
compute_hash(string) // Returns = NTliYzEyNTg0MDczM2VhODI4ZjQyZTI3NjY2MWIwMWUxNzdmMTQxNA== (but I need "WbwSWEBzPqgo9C4nZmGwHhd/FBQ=")
You need to instruct PHP to return the SHA1-hash in bytes instead of in hex format, by passing the TRUE parameter to the hashing function:
function compute_hash($string){
return base64_encode(sha1($string, TRUE));
}
PHP manual for SHA1
Related
I need to return few values from rust function. Tried to declare function which returns an array
$ffi = FFI::cdef('float get_arr()[2];', './target/release/libphp_rust.dylib');
$array = $ffi->get_arr();
But got an error:
PHP Fatal error: Uncaught FFI\ParserException: function returning array is not allowed at line 1 in /array.php:3
It seems PHP FFI can't work with arrays directly. So I found another solution.
I created C-array from PHP, then passed pointer to it to Rust code and then populated it with Rust function:
$ffi = FFI::cdef('bool get_arr(float (*res)[2]);', './target/release/libphp_rust.dylib');
$array = $ffi->new('float[2]');
$result = $ffi->get_arr(FFI::addr($array));
if ($result) {
var_dump($array);
} else {
//... something went wrong
}
#[no_mangle]
pub extern fn get_arr(array_pointer: *mut [f32;2]) -> bool {
let res = unsafe {
assert!(!array_pointer.is_null());
&mut *array_pointer
};
res[0] = 0.1;
res[1] = 0.2;
return true;
}
This solutions seems to work correct but i have some doubts about it:
Is passing pointers to FFI safe enough and what problems may I face with this in future?
Are Rust arrays fully C-compatible so that I'm able to assign value to it directly by index?
I there better way to achieve what I need? Or maybe are there some good practices about passing complex data structures with FFI?
Thanks
The rules surrounding this are still up in the air, so your example is questionably safe. This should be ok, but requires nightly features:
#![feature(maybe_uninit_extra)]
#![feature(ptr_as_uninit)]
// Make sure you use `extern "C"`. `extern` alone means `extern "Rust"`.
#[no_mangle]
pub extern "C" fn get_arr(array_pointer: *mut [f32; 2]) -> bool {
let fat: *mut [f32] = array_pointer;
let res = unsafe { fat.as_uninit_slice_mut().unwrap() };
res[0].write(0.1);
res[1].write(0.2);
true
}
On the stable channel it's just less elegant:
// Make sure you use `extern "C"`. `extern` alone means `extern "Rust"`.
#[no_mangle]
pub extern "C" fn get_arr(array_pointer: *mut [f32; 2]) -> bool {
assert!(!array_pointer.is_null());
unsafe {
let res = array_pointer as *mut f32;
res.add(0).write(0.1);
res.add(1).write(0.2);
}
true
}
I have a project I'm working on that uses an API for it request, but in order to preform them I need to generate the token first.
Before the API was update everything was working, after the update I don't know how to adjust my code to make it work again.
This was the code that worked before the update (Android | Kotlin):
fun hmacHash(str: String, secret: String): String {
val sha256HMAC = Mac.getInstance("HmacSHA256")
val secretKey = SecretKeySpec(secret.toByteArray(), "HmacSHA256")
sha256HMAC.init(secretKey)
return convertToHex(sha256HMAC.doFinal(str.toByteArray()))
}
fun convertToHex(data: ByteArray): String {
val buf = StringBuilder()
for (b in data) {
var halfbyte = (b.toInt() shr 4) and (0x0F.toByte()).toInt()
var two_halfs = 0
do {
buf.append(if (halfbyte in 0..9) ('0'.toInt() + halfbyte).toChar() else ('a'.toInt() + (halfbyte - 10)).toChar())
halfbyte = (b and 0x0F).toInt()
} while (two_halfs++ < 1)
}
return buf.toString()
}
Which was equivalent to this PHP code:
hash_hmac('sha256', $string, $privateKey);
But now after the update the php code looks like this:
hash_hmac('sha256', $string, hex2bin($privateKey));
And I don't know how to adjust my code to make it work with this new change.
From what I can deduce, the PHP code made that change because $privateKey went from being plain text to being hex-encoded. So hex2bin was needed to change it back to plain text (hex2bin changes hex-encoded text to plain text; a confusingly named function if you ask me).
Since your secret is plain text, you don't need to change anything to match. But there are other ways to improve your code. For example, converting a byte array to a hex-encoded string is much easier than that.
fun hmacHash(str: String, secret: String): String {
val sha256HMAC = Mac.getInstance("HmacSHA256")
val bytes = secret.toByteArray()
val secretKey = SecretKeySpec(bytes, "HmacSHA256")
sha256HMAC.init(secretKey)
return convertToHex(sha256HMAC.doFinal(str.toByteArray()))
}
fun convertToHex(data: ByteArray): String =
data.joinToString("") { "%02x".format(it) }
I'm currently rewriting an asp classic site in PHP, everything so far has been simple until I reached the password hashing function. In PHP I've used hash_hmac and hash, but I seem unable to replicate this functions results using a static salt in PHP. Please could someone help guide me as to how to produce the same result in PHP?
<% Function Hash(strPassword, strIndividualSalt)
Const strSiteWideSalt = "Bacon and HASH is best served with a good Salt!"
Hash = HashSHA512Managed(strSiteWideSalt & strPassword & strIndividualSalt)
End Function
Function HashSHA512Managed(saltedPassword)
Dim objMD5, objUTF8
Dim arrByte
Dim strHash
Set objUnicode = CreateObject("System.Text.UnicodeEncoding")
Set objSHA512 = Server.CreateObject("System.Security.Cryptography.SHA512Managed")
arrByte = objUnicode.GetBytes_4(saltedPassword)
strHash = objSHA512.ComputeHash_2((arrByte))
HashSHA512Managed = ToBase64(strHash)
End Function
Function ToBase64(rabyt)
Dim xml: Set xml = CreateObject("MSXML2.DOMDocument.3.0")
xml.LoadXml "<root />"
xml.documentElement.dataType = "bin.base64"
xml.documentElement.nodeTypedValue = rabyt
ToBase64 = xml.documentElement.Text
End Function
response.write Hash("mypassword", "mysalt")%>
This outputs...
1Asf3PuLZetBni4laI7jDKG3fbhlzKzB41G2694oZdH6nELLXklqtvY8Tniqjf3/2/gGg01fzs4w67l1Tfs20A==
Should I be using hash_hmac? Or do I need to replicate the function in PHP using hash()? Any help would be appreciated.
I am converting .net project to PHP . But unable to convert the following code:
public static string HashString(string value)
{
SHA1 hasher = new SHA1CryptoServiceProvider();
UTF8Encoding enc = new UTF8Encoding();
byte[] hashInBytes = hasher.ComputeHash(enc.GetBytes(value));
return Convert.ToBase64String(hashInBytes);
}
So far I have done this but result is not same:
function HashString($str) {
return base64_encode(sha1($str));
}
Please help, thanks.
The reason behind the difference is, PHP uses ASCII encoding for hash calculations.
In C#, you can replace UTF8Encoding with ASCIIEncoding in order to have same results.
Finally I found the solution:
This is the final code which is equivalent to .net code:
function HashString($str) {
return base64_encode(sha1($str,true));
}
I have added "true" with sha1 function.
I'm writing a php extension using c++. The c++ function signature is:
bool validateAndNormalizeStr (string& str)
Here 'str' is a in-out parameter. It's value would be updated in the function.
I hope the php function has the same signature. Here is a use case:
$str = " zh-hans-cn";
$ret = validateAndNormalizeStr($str);
if($ret)
{
echo $str;
}
I hope the output is: "zh-Hans-CN".
The problem is I haven't found any document about in-out parameter handling in writing php extension. Help!!!
Thanks