I'm working with an application that requires sha1 encoding for certain form values.
The problem is that when I use the following
<?php echo(hash("sha1","par1=".$_POST['p1']."&par2=".$_POST['p2'])); ?>
It gives me a sha1 encoding of the actual string, while I want to get a sha1 encoding of the posted values, so in this example I want to get
<?php echo(hash("sha1","par1=firstvalue&par2=secondvalue")); ?>
How can I realize this? Is it actually that simple and am I thinking way to difficult?
That because it identifies that para1=some_value as string not para1 as variable and some_value string
To achieve what you want you should hash every variable alone
Or I suggest that you implement your own encoding algorithm
Why not do it like this? Though I would have though either way would result in the same thing....
$hash_this = "par1=".$_POST['p1']."&par2=".$_POST['p2'];
echo sha1($hash_this);
Though that will do it if you want to hash the string of the values all together, rather than the values, if you want to store the values - then you should probably hash each value, so you could at least compare them later. Useful for a login system where you want to save a password to a database, which is more secure than literally just storing the password...
$password = sha1($_POST['password']);
If you hash the string, you have no idea which value is wrong
Related
I am using the following function to encrypt a string ($str) using a key ($key) to make a unique key.
Sample Code:
<?php
$key = "####";
$str = "123456789";
$encrypted_key = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $str, MCRYPT_MODE_CBC, md5(md5($key))));
echo $encrypted_key; // 3rfmDKb/Ig5FuUnkY8fiHpqA3FD4PflXMksJw+6WAns=
?>
The function is returning values consisting special characters including '+' . I am storing this values in database as a unique ID.
However in certain conditions, I need to pass the $encrypted_key through URLs . i.e; for using it with RESFful web services
Sample URL:
www.example.com/index.php?encrypted_key=3rfmDKb/Ig5FuUnkY8fiHpqA3FD4PflXMksJw+6WAns=
But this when requested through URL will decode '+' into 'spaces'
Code:
echo $encrypted_key = $_REQUEST['encrypted_key'];
// 3rfmDKb/Ig5FuUnkY8fiHpqA3FD4PflXMksJw 6WAns=
This conversion is further affecting the DB checks :
'3rfmDKb/Ig5FuUnkY8fiHpqA3FD4PflXMksJw 6WAns=' against '3rfmDKb/Ig5FuUnkY8fiHpqA3FD4PflXMksJw+6WAns='
Also I am having a concern of storing these encrypted values into indexed MySQL DB columns.
What should be the best practice to be adopted here? Any advise will be highly appreciated.
This answer only addresses the representation, not the likely-to-be-wrong use of crypto.
When you build objects that have special representation rules like database queries, paths in URLs, HTML code, JS code, and so on, you must ensure that you perform the proper kind of encoding of the values so that they roundtrip without harm.
For database query parameters, do not use string concatenation. Use prepared statements and placeholders.
For URLs, use the proper URL encoding function or an URL builder to construct your URL, do not blindly concatenate strings.
First, is not a good idea to use encrypted values as Unique ID or as Conditional Field, because they will change for the same value. This is very commom in encryption. If an encryption algorithm don't change the result for the same entry, it is not a good encryption.
Second, I had the same problem to deal with encryption and URL, and in my case a made my own encryption algorithm, using only valid characters for URL.
It is not dificult to implement an encryption: I used the ASCII code, one simple key, one simple math function, and nothing more. To decryption, I "reversed" the math function.
So if I do something like sha1($data) the result will be BLAHBLAH123. However if I do it again it will be BLAHAHS316. The same thing happens with md5. So my question is, what is a consistent way to hash values?
So like function($data) will return BLAHBLAHBLAH123 each time it is evaluated with the same $data parameter.
EDIT: I have a specific purpose in mind for this that isn't passwords so security isn't a concern.
EDIT: For example, md5($data) will not return BLAHBLAH every time, sometimes it'll return BLAHHHAL. I don't want that. I want it to return the same thing, BLAHBLAH everytime!
The output of a hashing operation will only change if the input has changed.
For example:
echo sha1( 'test' );
a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
If you wish it to change everytime, you could append a timestamp to the input:
echo sha1( 'test'.time() )
3d68b7693768f199623f31f820b1ba29b0a58769
Hashing function are deterministic (they would be useless if this was not the case).
In computer science, a deterministic algorithm is an algorithm which, given a particular input, will always produce the same output, with the underlying machine always passing through the same sequence of states.
Consider another (eg. time) input to the domain as in sha1(microtime() . $data) if you want 'different output'. I'm not sure how useful this will be in practice.
Password hash functions use a salt (randomly generated, stored separately) as additional input so the same plain-text password will result in a different stored hash value.
Hashing method - to give the same value, but not easy to predict or decode is what i think you are looking for.
You can use use a constant string val and do a hash of that string to get the same value always, if you want to change the value you can change the constant and get a different hash value
$constStr = "hashThis";
$hashWord = md5($constStr);
// it will return the same value always, as long as the constStr is the same
Two different input with same md5 or sha1 output?
That's possible but way to hard. Take a look at here: https://crypto.stackexchange.com/questions/1434/are-there-two-known-strings-which-have-the-same-md5-hash-value
The return value will change as long as your $data variable changes, you can't get same hashing value from different strings
Let's say we need to store in a crypted way some confidential data into a db. And say that we need them into json format as will be more suitable for data reconstruction.
There's something that I miss that is driving me crazy.
Take that json for instance
$json = {"customer":{"customer_address":"Fake address 123","customer_city":"Fake City","customer_company":"","customer_countrycode":"it","customer_email":"","customer_telephone":"+39.347.xxxxxxx","customer_zip":"yyyyy"},"currency_code":"EUR","commision_amount":"84"}
now I want to crypt this json and I do the following
$pubKey = openssl_pkey_get_public($puk);
openssl_public_encrypt($json, $json_crypted, $pubKey);
if I echo $json_crypted it doesn't show anything, but if I remove some field (like customer_company, that is empty) all seems to work. I've tried to find something into documentation about this strange behaviour but I can't find anything.
Is someone aware of the reason behind that result?
Edit
Even if I remove other field (not an empty one) all seems to work. I'm speechless because it has to be a silly thing that I can't understand
From the comments in documentation:
http://www.php.net/manual/en/function.openssl-public-encrypt.php#95307
openssl_private_encrypt() has a low limit for the length of the data
it can encrypt due to the nature of the algorithm.
To encrypt the larger data you can use openssl_encrypt() with a random
password (like sha1(microtime(true))), and encrypt the password with
openssl_public_encrypt(). This way the data can be encrypted with a
public key and decrypted with the private one.
Your json must exceed the length limit...
So I have this really weird problem. I have a login script and you type in a username and password. Once the password is posted i sha1 it with the php function sha1() and compare that to the sha1 version in the database. If they match it logs in. That part works fine. Now I have the same functionality for a mobile version, but it uses a different form and a different URL. After you type in the password I do all the exact same steps, but the sha1 hash that is posted is different than the sha1 hash in the database. I know I type them in exactly the same each time, so I don't see why the two values would be different. This is only true for some username / password combination. Am I missing something??
There is no reason for the same text produce different sha1 values.
I suggest you log the real password values before the sha1 is generated to debug the problem.
I suspect that you may be entering passwords with different case or are padded with spaces or other characters for some reason.
I ve had this problem and i could not trace it. It turns out that if you enclose the input string in sigle quotes yields different results than with double quotes.
Also watch out for different encoding issues
Example
$str = "test=!$E0";
$enc = mb_detect_encoding($str, "UTF-8,ISO-8859-1");
echo strtoupper(sha1(iconv($enc, "UTF-8",$str)));
04CDF156D64CC4B51E1DC7E5A852F9177102EBE7
$str = 'test=!$E0';
$enc = mb_detect_encoding($str, "UTF-8,ISO-8859-1");
echo strtoupper(sha1(iconv($enc, "UTF-8",$str)));
44372F3C82A4AAD84748AE5ECB8F6C7313DA6C65
Very annoying
I was attempting to
encrypt de cookie data with md5, but I can not validate the hash back.
It has got to do, with the fact that cookie_data is a serialized array, because normal stringvalues work ok.
It's actually from a codeigniter class, but it does not work??
Does anyone know what the problem might be?
$hash = substr($session, strlen($session)-32);
$session= substr($session, 0, strlen($session)-32);
if ($hash !== md5($session.$this->encrypt_key))
{........
and the cookie value is encrypted like this
$cookie_data = $cookie_data.md5($cookie_data.$this->encrypt_key);
EDIT
I found that the answer is to use urlencode en urldecode in the proces of creating and validate
md5 hashes, because setcookie does urlencode automaticly, and thereby possibly changing the hash.
thanks, Richard
You have a typo:
md5($sessie.$this->encrypt_key))
should be
md5($session.$this->encrypt_key))
If you develop with notices turned on you'll catch this kind of thing much more easily.
You're not encrypting your data, you're signing it.
md5 is a oneway function. It is not a reversible one, so you can't decrypt the data.
The only thing you can do is encrypt the original data (if you saved it elsewhere) and check the result of this second computation.
If the value retrieved and the new value calculated are the same, the hash you received is valid (As you are doing in your code).
EDIT
You know, with just three lines of code I will guess some possible causes:
$session doesn't contains at the beginning of your code the same value of cookie_data.
you are using multibyte strings and strlen is not mb aware (use the idioms substr($session,0,-32) to get the payload part of the string.
maybe substr doesn't cope with multibyte strings too, use explicitally mb_substr (or whatever it is called).
To me the first case is the more probable. For what I can see.
I was attempting to encrypt de cookie
data with md5, but I can not decrypt
it back for validation.
md5 isnt an encryption method. it creates a one-way hash that cant be turned back into the original data.
If you want to encrypt data try mcrypt