Hashing multiple values - most secure method? - hash

hash(value1 & value2 & salt)
hash(hash(value1 & value2) & salt)
hash(hash(value1 & value2) & hash(salt))
hash(hash(value1 & salt) & hash(value2 & salt))
hash(hash(value1 & salt1) & hash(value2 & salt2))
hash(value1 & salt1 &value2 & salt2)
hash(value1 & salt1) and hash(value2 & salt2) '2 separate hashes for each input
In an application where 2 'passwords' are needed to access a specific function (for whatever reason you want) and the salt(s) are large random strings. What would be the best way of getting a final hash to store? (not necessarily 1 of the above)
Is it 'better' to have the outside/final hash algorithm different to the inner ones?
Side question: is a salt mainly for making short, crappy user pw's more secure from brute force attacks? So if the pw was large (say the ByteArray of an image file) would a salt add any real purpose? Thanks.

Assuming & means concatenation, the safest is:
hash(value1 & delim & value2 & delim & salt)
...where delim is a delimiter that cannot appear in any of the other strings. It doesn't matter which order value1, value2 and salt appear in.
The delimeter prevents aliasing, e.g., (value1, value2) = ('fail', 'stone') vs (value1, value2) = ('fails', 'tone').

Related

How to treat special character when casting string kdb

When casting a value to a string (via "string" keyword)
Ex.
t:([]stuff:`a`b`c)
select string stuff from t
Adds a weird special character before final 0a when calling from k function (via C client)
0x0180
What is this ? What is best way of handling it ? Is there anyway to get a string without this special character ?
stuff,more
a,1.2�
b,2.3�
c,3.4�
The special character does not appear in a q session
q)select string stuff from t
stuff
-----
,"a"
,"b"
,"c"
so one supposes your problem arises from the C API. Not being familiar with the API, the rest of this is speculative. Sorry.
If you are working through the API, perhaps you do not need a table returned, only the column values. Is exec perhaps closer to what you want?
q)exec string stuff from t
,"a"
,"b"
,"c"
If so, do you still see the character you ask about?

Random string vs hashed and salted string

Say I want to create a password that is purely random, call it randPass of size 32 characters.
Is there any advantage in terms of security of using this directly as a password, vs hashing and salting it (like md5(randPass + salt)?
I mean at the end of the day, they will both be a 32 character long random characters.
Here is a dummy example:
salt = SFZYCr4Ul1zz1rhurksC67AugGIYOKs5;
randPass = VgQK1AOlXYiNwfe74RlU8e8E4szC4UXK;
Then the md5(randPass + salt) = md5(VgQK1AOlXYiNwfe74RlU8e8E4szC4UXKSFZYCr4Ul1zz1rhurksC67AugGIYOKs5) becomes
hash = dddbc2cbda808beeb7e64ce578ef4020
The main advantage of a RANDOM salt is that you cannot run a dictionary attack against the hash table since each password should have a different salt, thus "Password" and salt "jfadljfadiufosd38120809321" turns into "Passwordjfadljfadiufosd38120809321" which is definitely not in a pre-computed dictionary md5 hash dictionary so you cannot do a reverse lookup and figure out the users password.
By using a hash you are limiting the characters in the password.
Hash characters are: range(0,9) and range('a','f').
More characters is better.
If the password is to be submitted to a web page then the symbols should not include those commonly used in sql injection. (e.g. ",',%,\)
To eliminate symbols change range('!','#') to range('0','9')
Set your criteria for how many and what characters and symbols are allowed.
This algorithm uses upper case, lower case, numeric and symbols.
Length of 32 characters.
$characters = array_merge(
range('a','z'),
range('A','Z'),
range('!','#'));
shuffle($characters);
shuffle($characters);
$characters = array_flip($characters);
$ndx = 33;
$pass = '';
while($ndx-->1){
$pass .= array_rand($characters);
}
echo $pass;

Does adding two hash values generate a valid hash?

Does adding 2 hash values generate another valid hash value? In other words will this hash(a) + hash(b) != hash(c) + hash(d) always be true? I don't think it will but does it matter? Are the essential properties of the hash function preserved under addition?
Since several values can have the same hash, it could be that hash(a) = hash(b) = hash(c) = hash(d), so also hash(a) + hash(b) = hash(c) + hash(d).
A hash, by the pidgeonhole theorem, can't be collision free. So hash(a)+hash(b) == hash(c)+hash(d) for some values of a, b, c, and d. Adding hash functions still gets you the good qualities of the hashes that you added together, but it won't make the result any better than the better of the two. (You're not increasing your hash table space.)On second thought, the result will be only as good as the worse hash that you added.
This depends on your hashing algorithm, and in general it will not be true. Given a finite hash table, any two hash keys near the end of the table when added together will clearly give you a hash key off past the limit of your legal hash values.
I'm working under the assumption that when you say "hash" you're refering to a cryptographic one like MD5 or SHA1, if you're talking about something else... ignore me.
Adding hashes together would be kind of a weird process, XORing them might make more sense... ish.
It's possible for hash(a) + hash(b) == hash(c) + hash(d), but incredibly unlikely. By merging the two hashes you're creating the possibility (though there's the possibility that hash(a) == hash(c) off the boat, it's just slim). Hashing identical items would clearly result in equality.
Your question expressed in English doesn't match the expression you give. Do you want to know if:
hash(a) + hash(b) != hash(c)
will always be true?
The answer is no. Any value might be a valid hash value.

Verifying salted hashes with Perls unpack()

I'm trying to verify salted passwords with Perl and am stuck with unpack.
I've got a salted hashed password, e.g. for SHA256: SSHA256 = SHA256('password' + 'salt') + 'salt'
Base64 encoded that gets '
{SSHA256}eje4XIkY6sGakInA+loqtNzj+QUo3N7sEIsj3fNge5lzYWx0'.
I store this string in my user database. When a user logs in need to separate the salt from the hash to hash the supplied password with the salt and compare the result to the one retrieved from the db. This is where I'm stuck. I don't seem to have the right unpack template separate the hash (8-bit binary, fixed length, in this case 32 byte) from the salt (8-bit binary, variable length).
I have tried something like
my ($hash, $salt) = unpack('N32 N*', $data);
but that doesn't seem to work out.
My question is: How can I unpack this hash (after it has been Base64 decoded) to get the fixed length hash in one and the variable length salt in another variable?
I think you're needlessly re-inventing the wheel.
You could use e.g. Crypt::SaltedHash to easily verify it, for instance:
my $password_entered = $cgi->param('password');
my $valid = Crypt::SaltedHash->validate($salted, $password_entered);
A longer example, showing using Crypt::SaltedHash to generate the salted password in the first instance, too:
my $csh = Crypt::SaltedHash->new(algorithm => 'SHA-256');
$csh->add('secretpassword');
my $salted = $csh->generate;
# $salted will contain the salted hash (Crypt::SaltedHash picks random
# salt for you automatically)
# for example:
DB x $salted = $csh->generate;
0 '{SSHA256}H1WaxHcyAB81iyIPwib/cCUtjqCm2sxQNA1QvGeh/iT3m51w'
# validating that against the plaintext 'secretpassword' shows it's right:
DB x Crypt::SaltedHash->validate($salted, 'secretpassword');
0 1
# and trying it with an incorrect password:
DB x Crypt::SaltedHash->validate($salted, 'wrongpassword');
0 ''
No reason to re-invent all of this yourself.
You seem to be doing RFC2307 the hard way and also manage to introduce bugs. Those + do not mean what you think.
Subclass Authen::Passphrase::SaltedDigest instead.
Not sure the whole picture is present, but the unpack template you have specified -'N32 N*'- is for 32 unsigned long (32-bit) (big-endian) integers (see pack docs).
Looks like you may instead need unsigned chars: '32C C*'

How should I generate a random alphanumeric initial password for new users?

We have to automatically import a large list of users with some data into a running system.
For an initial password I want to update the list (csv format at the moment) with a random alphanumeric key (8 digits).
When inserting it with a special routine (which needs a csv file), the password (in this case the alphanumeric key) is stored as a md5 hash.
i.e. I generate a random alphanumeric key:
H2A5D39A -> MD5: 1642fccf791f15d137cf31282af79752
This way I want to create a list where authenticated users can ask me for their initial password (the alphanumeric key).
Do you have a better idea for a "secret" initial password?
How would you create the alphanumeric key in Perl?
P.S.: The "running system", not programmed by us, just allowes alphanumeric passwords (no special chars,...)
How would you create the alphanumeric key in Perl?
join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..8
I would probably use pwgen. It is great as it allows easy customization, and has the switch not to use ambiguous characters (think: I, l, 1, O, 0).
for example:
=> pwgen -c -n -B 8 50
shuFak9o peiCh3Oo ohPieng9 Vohh7zuu os3Theep aeV9nuo9 aexeik4B aeChoh9s
uth3eePu baePhu3o aiS3pahn iPie4itu We9zuphi xie3Chi3 yeiRoo7c fai3ITai
aCh9ohco Echuab7v Fu9ahCho Aevae4no Peethai9 AiJio3Pa aeNge9Fo baePh7Uy
Nai7shei eeMoh9en Zeibai4n eGe7yuch Jaek7nai aeZah7sh Chei4ua4 shoo9oG9
iu7Wohho aep7De4U Fong9fo3 AhneeP7U oxae7Yoh ahF4eim3 fahm9Aiw naoNg4ie
Chie4xua jix3Uvot aChei7ai diey4Shi Yur7ee4j eeJeo9ee Bou3ahmu kaeb4Cah
Eh4Eemae oD4phoo9
Anonymous's answer is very good, but, if you need a random string that conforms to some rules (such as at least one uppercase, one lowercase, and one number), you may want to look into String::Random.
Another module to consider is Data::Random
I just completed a review of the 12 modules on CPAN that can be used to generate random passwords:
http://blogs.perl.org/users/neilb/2011/08/random-password-generation.html
In short: if you want a pronounceable password, look at Crypt::YAPassGen,
otherwise go for App::Genpass.
App::Genpass avoids confusable characters and gives you better control (and defaults) than Data::Random or String::Random