Decode multiple variables coded by MD5 - php

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.

Related

How to verify password hash ( hash_hmac, sha512 ) in php?

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.

Questions about password security in PHP/MySQL

function password_encrypt($password) {
$hash_format = "$2y$10$"; // Tells PHP to use Blowfish with a "cost" of 10
$salt_length = 22; // Blowfish salts should be 22-characters or more
$salt = generate_salt($salt_length);
$format_and_salt = $hash_format . $salt;
$hash = crypt($password, $format_and_salt);
return $hash;
}
function generate_salt($length) {
// Not 100% unique, not 100% random, but good enough for a salt
// MD5 returns 32 characters
$unique_random_string = md5(uniqid(mt_rand(), true));
// Valid characters for a salt are [a-zA-Z0-9./]
$base64_string = base64_encode($unique_random_string);
// But not '+' which is valid in base64 encoding
$modified_base64_string = str_replace('+', '.', $base64_string);
// Truncate string to the correct length
$salt = substr($modified_base64_string, 0, $length);
return $salt;
}
Do you guys thnk this is secure? What could have been done differently? What's maybe easier to use to secure a password and hash it?
Blowfish itself is already really secure. One thing: don't do too much hashing etc. to generate a salt. Also, why not make it easier and use password_hash?
http://php.net/manual/en/function.password-hash.php
Example:
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT)."\n";
And to check a password:
if (password_verify($password_nonhashed, $password_hashed)) {
You don't need to hash a salt too much with blowfish. Just use sha1 hash for a salt if you really don't want to use password_hash.
Good luck!

SCRAM-SHA-1 auth by 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.

ActionScript 3 md5-bin from string

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));

How to properly generate a WSSE Password Digest in PHP

I'm looking at building a REST API in Symfony2, and in their Custom Authentication Provider they show how to build a WSSE authentication system, which should be fine for what I need to do. I'm going to start off by building and testing the API through cURL, so I need to be able to quickly generate the headers. I found a JS generator that showed the headers I would need.
From what I read, the Password Digest should be a base64 encoded SHA1 of the nonce, timestamp, and user password concatenated together in that order. I started with the following data:
$nonce = '4c5625ec7af5bdff';
$timestamp = '2013-04-03T04:46:19Z';
$password = 'mypass';
and generated the digest:
$digest = base64_encode(sha1($nonce.$timestamp.$password));
What I don't understand is that the $digest variable is now set to YTgxMDUzOWQzMDBiZmU1MmI2NWQ0YjYwNDc3ZmY5OWI3MmVlZTQyNA==, but the sample PasswordDigest from the JS generator comes up as qBBTnTAL/lK2XUtgR3/5m3Lu5CQ=. I must be missing a step somewhere, but I'm not sure what it is.
Looks like I need to use the binary SHA1 result, not the hex representation. My digest should look like this:
$digest = base64_encode(sha1($nonce.$timestamp.$password, true));
I know it's an old post, just tumbled on this post, recently I have developed API in symfony2 with WSSE authentication and this is how I generated full WSSE header with the help of below function:
public static function getWsseHeader($username, $apikey, $created, $nonce)
{
$digest = sha1($nonce.$created.$apikey, true);
return sprintf(
'X-WSSE: UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"',
$username,
base64_encode($digest),
base64_encode($nonce),
$created
);
}
//you can use this php code to generate the Digest password
<?php
date_default_timezone_set('UTC');
$t = microtime(true);
$micro = sprintf("%03d",($t - floor($t)) * 1000);
$date = new DateTime( date('Y-m-d H:i:s.'.$micro) );
echo $timestamp = $date->format("Y-m-d\TH:i:s").$micro . 'Z';
$nonce = mt_rand(10000000, 99999999);
echo $nounce = base64_encode($nonce);//we have to decode the nonce and then apply the formula on it and in xml we have to send the encoded nonce
$password = "AMADEUS"; //clear password
echo $passSHA = base64_encode(sha1($nonce . $timestamp . sha1($password, true), true));
?>

Categories