How can I get a similar procedure in AS3
$hash = md5('string', true);.
$hash = strtr(base64_encode($hash), '+/', '-_');.
echo "$hash \n";
rezult:tFz_4ITdPSDZKL7oXnsPIQ==
I can get md5-bin from a string
You need a third party library.
I suggest as3crypto
And here is an EXAMPLE
as3crypto return a md5 hash-string 32 simbols, I need raw output 16 simbols.
I need to make nginx secure link
http://wiki.nginx.org/HttpSecureLinkModule#Example_usage:
$md5 = base64_encode(md5($secret . $path . $expire, true)); // Using binary hashing.
RESOLVED:
var md5_hash:String = MD5.hash('string');
var hash:String = Base64.encodeByteArray(Hex.toArray(md5_hash));
Related
I need to convert VerifyPasswordHash method in C# to php. I have salt and stored_hash in DB for this user.
stored_hash = 0x0C3F6C5921CCD0305B2EDEDE1553B1DF55B87A9D55FEE3384A3833611BC40D106BBB48CCE1093AE35B9D0E3A1FE62E86186A6EC143BA00E53945E99C259B4913
salt=0xC62C5A645280DBCC615ED4A3E861D800B00A929856A9664B3AED50A06481ED19AFB09F74D3D7A9EA25327D93F23FDFBD2DE8CF3A75D65A3EA97290E0486F1F4322D2B5853AE6FE848E50355C35B62A993CF6689D9F9ABC861C5E7D88B099617E6A6C7792E285EFBB809FD69CD926C9BD9129AD1BE7DDB5DD459C2B9A2B945B31
Here is example in C#:
`
private bool VerifyPasswordHash(string password, byte[] storedHash, byte[] storedSalt)
{
using (var hmac = new System.Security.Cryptography.HMACSHA512(storedSalt))
{
var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
for (int i = 0; i < computedHash.Length; i++)
{
if (computedHash[i] != storedHash[i])
{
return false;
}
}
}
return true;
}
Here is what I tried in PHP:
`
<?php
$password = 'Password202!';
$pass_hash = '0x0C3F6C5921CCD0305B2EDEDE1553B1DF55B87A9D55FEE3384A3833611BC40D106BBB48CCE1093AE35B9D0E3A1FE62E86186A6EC143BA00E53945E99C259B4913';
$pass_salt = '0xC62C5A645280DBCC615ED4A3E861D800B00A929856A9664B3AED50A06481ED19AFB09F74D3D7A9EA25327D93F23FDFBD2DE8CF3A75D65A3EA97290E0486F1F4322D2B5853AE6FE848E50355C35B62A993CF6689D9F9ABC861C5E7D88B099617E6A6C7792E285EFBB809FD69CD926C9BD9129AD1BE7DDB5DD459C2B9A2B945B31';
function VerifyPasswordHash($password,$pass_hash,$pass_salt){
$password_utf8 = utf8_encode($password);
$sig = hash_hmac('sha512', $pass_salt, $password_utf8, true);
echo base64_encode($sig);
}
VerifyPasswordHash($password,$pass_hash,$pass_salt);
I know that i need to compare $sig and stored_hash but they don`t even match.. Any help would be appreciated!
Expected result is successful comparison of $pass_hash and computed_hash. I simply need to verify password
There are a few things wrong with your code, but you're almost there.
Firstly, drop the utf8_encode(). This rarely does what you expect and, as #Chris mentioned in a comment, the function has been deprecated and will be removed in the future.
According to the manual, the data to hash comes before the key (salt), so you have your parameters in the wrong order:
$sig = hash_hmac('sha512', $password, $pass_salt, true);
// $password first, then $pass_salt
Next, you're using base64_encode. That is not what you want, you're looking for a hexadecimal representation of the created signature. You're looking for bin2hex():
echo bin2hex($sig);
However, this has the same effect as just passing false as the final argument to hash_hmac -- the true argument indicates you want a binary result, then you're turning it into hexadecimal representation. Passing false will return the hexadecimal notation instead of a binary result so you can skip the bin2hex step:
$sig = hash_hmac('sha512', $password, $pass_salt, false);
echo $sig;
The final problem is the notation of the salt. PHP does not use the 0x prefix for hexadecimal strings. After a bit of trial-and-error, I also found that the correct way to calculate the hash is to actually use the binary representation of the hexadecimal salt-string (using hex2bin, the reverse of bin2hex):
function VerifyPasswordHash($password,$pass_hash,$pass_salt){
// The substr() removes the leading "0x" from the salt string.
$sig = hash_hmac('sha512', $password, hex2bin(substr($pass_salt, 2)), false);
echo $sig;
}
For the values you provided, this outputs:
0c3f6c5921ccd0305b2edede1553b1df55b87a9d55fee3384a3833611bc40d106bbb48cce1093ae35b9d0e3a1fe62e86186a6ec143ba00e53945e99c259b4913
This matches your sample hash, if you'd uppercase it and put the redundant "0x" in front of it:
function VerifyPasswordHash($password,$pass_hash,$pass_salt){
$sig = hash_hmac('sha512', $password, hex2bin(substr($pass_salt, 2)), false);
$hash = '0x' . strtoupper($sig);
return $hash === $pass_hash;
}
This returns true for the given sample hashes.
I have the coding of this variables:
$secret = 'jsdkhf8fh3fewk';
$path = '/foo.pdf';
$expire = time() + 3600; // one hour valid
$md5 = base64_encode(md5($secret . $path . $expire, true));
$md5 = strtr($md5, '+/', '-_');
$md5 = str_replace('=', '', $md5);
Is there a way to rollback to the original variables $secret,$path and $expire?
The problem is that this $md5 is part of url and it is used to validate the request. How server can validate request with it?
Hashing is not encryption. MD5 is a hashing algorithm. Hashing is one-way, so you cannot decrypt an hash. What you can do is try to guess the original $secret . $path . $expire string by try to match a large number of possible combination. But even then md5 isn't a collision-resistant hash function, so there are no guarantee even then.
I have to build an authorization hash from this string:
kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F
This secret is used for a HMAC hash function:
LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=
The authorization hash I have to generate is this:
P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=
There are some things to take care of:
The signature have to be built with HMAC-SHA-256 as specified in RFC 2104.
The signature have to be encoded with Base64 URL-compatible as specified in RFC 4648 Section 5 (Safe alphabet).
There is also some pseudo-code given for the generation:
Signatur(Request) = new String(encodeBase64URLCompatible(HMAC-SHA-256(getBytes(Z, "UTF-8"), decodeBase64URLCompatible(getBytes(S, "UTF-8")))), "UTF-8")
I tried various things in PHP but have not found the correct algorithm yet. This is the code I have now:
if(!function_exists('base64url_encode')){
function base64url_encode($data) {
$data = str_replace(array('+', '/'), array('-', '_'), base64_encode($data));
return $data;
}
}
$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F";
$sec = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=";
$signature = mhash(MHASH_SHA256, $str, $sec);
$signature = base64url_encode($signature);
if($signature != "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=")
echo "wrong: $signature";
else
echo "correct";
It gives this signature:
K9lw3V-k5gOedmVwmO5vC7cOn82JSEXsNguozCAOU2c=
As you can see, the length of 44 characters is correct. Please help me with finding the mistake, this simple problem takes me hours yet and there is no solution.
There's a couple of things to notice:
Your key is base64-encoded. You have to decode it before you could use it with php functions. That's the most important thing you have missed.
Mhash is obsoleted by Hash extension.
You want output to be encoded in a custom fashion, so it follows that you need raw output from hmac function (php, by default, will hex-encode it).
So, using hash extension this becomes:
$key = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ=";
$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F";
function encode($data) {
return str_replace(['+', '/'], ['-', '_'], base64_encode($data));
}
function decode($data) {
return base64_decode(str_replace(['-', '_'], ['+', '/'], $data));
}
$binaryKey = decode($key);
var_dump(encode(hash_hmac("sha256", $str, $binaryKey, true)));
Outputs:
string(44) "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI="
Simply use hash_hmac() function available in PHP.
Example :
hash_hmac('sha256', $string, $secret);
Doc here : http://php.net/manual/fr/function.hash-hmac.php
help me please with implementing semantic code from manual about SCRAM-SHA-1 authorization in XMPP server. So, we got:
clientFinalMessageBare = "c=biws,r=" .. serverNonce
saltedPassword = PBKDF2-SHA-1(normalizedPassword, salt, i)
clientKey = HMAC-SHA-1(saltedPassword, "Client Key")
storedKey = SHA-1(clientKey)
authMessage = initialMessage .. "," .. serverFirstMessage .. "," .. clientFinalMessageBare
clientSignature = HMAC-SHA-1(storedKey, authMessage)
clientProof = clientKey XOR clientSignature
clientFinalMessage = clientFinalMessageBare .. ",p=" .. base64(clientProof)
My PHP code:
$cfmb = 'c=biws,r='.$salt;
$saltpass = hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $ps, $iter);
//hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $salt, $iter, 0, true); maybe like that???
$ckey = hash_hmac('sha1', $saltpass, 'Client Key');
$sckey = sha1($ckey);
$authmsg = $im.','.$chal.','.$cfmb;
$csign = hash_hmac('sha1', $sckey, $authmsg);
$cproof = bin2hex(pack('H*',$ckey) ^ pack('H*',$csign));
$cfm = $cfmb.',p='.base64_encode($cproof);
Somewhere error (maybe ALL big error ;)) and I very need your help for correcting my code, maybe I am use wrong functions, or arguments in wrong positions? Because result - fail, server sends me that:
"The response provided by the client doesn't match the one we calculated."
PS: Sorry for my bad English ;)
First of all, it's very confusing to use $salt for the serverNonce and $ps for the salt.
But more importantly, you should take some care to keep track of whether the functions you use return binary data or hexadecimal encoded strings. hash_pbkdf2, sha1 and hash_hmac by default return hexadecimal encoded strings. You call pack('H*', ...) to decode them for the $cproof, but not when you calculate $ckey and $csign.
A much easier way is to compute binary data directly, by always passing $raw_data = TRUE:
$cfmb = 'c=biws,r='.$salt;
$saltpass = hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $ps, $iter, 0, TRUE);
$ckey = hash_hmac('sha1', 'Client Key', $saltpass, TRUE);
$sckey = sha1($ckey, TRUE);
$authmsg = $im.','.$chal.','.$cfmb;
$csign = hash_hmac('sha1', $authmsg, $sckey, TRUE);
$cproof = $ckey ^ $csign;
$cfm = $cfmb.',p='.base64_encode($cproof);
Also, your hash_hmac calls were the wrong way around: first the data, then the key.
Usually, I use openssl_encrypt to encrypt simple string with AES in PHP, and it works pretty well.
Now I need to encrypt files with AES-256-CTR mode, but the only way to do this is to file_get_contents the entire content of the file and then send it to the openssl_encrypt function to encrypt the actual file data. The problem is this method is very "poor" because of the critical waste of memory.
1) Is there a way to work with chunked data with PHP OpenSSL ?
For example:
<?php
// ...
$f = fopen('large.iso','r');
while(feof($f)){
$chunk = fread($f,16);
$cipher = openssl_encrypt(...$chunk...);
// ... code ...
}
// ... more code ...
?>
2) openssl_encrypt official documentation is not published yet. Does someone could clarify the meaning of the parameters of the function for use with AES-CTR mode? Does the counter is handled automatically? Is it necessary to apply a manual XOR the data returned by the function?
Note: It is a professional project so I don't want to use phpseclib or others' "anonymous" libraries, nor do I don't want to use the command line as well.
Looks like for php it's not possible to use aes-256-ctr without temporary file.
But for next chiper types:
OPENSSL_CIPHER_RC2_40
OPENSSL_CIPHER_RC2_128
OPENSSL_CIPHER_RC2_64
OPENSSL_CIPHER_DES
OPENSSL_CIPHER_3DES
OPENSSL_CIPHER_AES_128_CBC
OPENSSL_CIPHER_AES_192_CBC
OPENSSL_CIPHER_AES_256_CBC
you can use generating key on the fly:
$res = openssl_pkey_new('chiper args here');
openssl_pkey_export($res, $private_key);
$public_key = openssl_pkey_get_details($res);
$public_key = $public_key["key"];
Then encrypt:
$crypted_text = openssl_get_privatekey($private_key,'your data');
And decrypt:
openssl_public_decrypt($crypted_text,$decrypted_text,$public_key);
So if you don't want to use files, may be switching to OPENSSL_CIPHER_AES_256_CBC will help you?
1) It should be something like this:
function strtohex($x) {
$s = '';
foreach (str_split($x) as $c){
$s.=sprintf("%02X", ord($c));
}
return($s);
}
$method = "aes-256-ctr"; //aes-256-cbc
echo "Selected method: ".$method."<br /><br />";
$textToEncrypt = "My chunk of data";
$iv = "1234567890123456";
$pass = 'some_pass';
$dec_iv = strtohex($iv);
$key = strtohex($pass);
$enc_data = openssl_encrypt($textToEncrypt, $method, $pass, true, $iv);
echo "Encrypted message (openssl): ".$enc_data."<br />";
$dec_data = openssl_decrypt($enc_data, $method, $pass, OPENSSL_RAW_DATA, $iv);
echo "Decrypted message (openssl): ".$dec_data."<br />";
For CTR $iv should be unique for each chunk or your data can be broken.
2) I know only abot difference betwen CBC and CTR:
For CBC, the IV must be random, but not unique. It also must not be known.
For CTR, the IV must be unique and not known, but does not need to be random.