How is it possible to compare hash values without referencing salt or saltRound? - cryptography

My question is about hashing procedure.
const bcrypt = require('bcrypt');
const saltRounds = 10;
var password = "Fkdj^45ci#Jad"; // Original Password
var password2 = "djlfhjd(456"; // Wrong Password
bcrypt.hash(password, saltRounds, function(err, hash) {
bcrypt.compare(password2, hash, function(err, result) {
...
});
});
This is a code snippet for hashing with salt and comparing.
I can't understand how it is possible to compare hash and password without knowing salt. bcrypt is using Blowfish now, but how is it possible for a having algorithm to compare a password and a hash value without knowing salt?

It isn't. The output of bcrypt.hash includes that information. For example, when I run your code, the value of hash is:
$2b$10$ytoRP21isLcU43jpdiDi4ebR5aKfydE.cHt6VkoH3suODa64JUvEy
This is the "2b" format, with a cost of 10, a salt of ytoRP21isLcU43jpdiDi4e (first 22 characters) and a hash of bR5aKfydE.cHt6VkoH3suODa64JUvEy (last 31 characters). The salt and hash are "radix-64 encoded," which is similar to Base64 encoding, but uses a different table.
When you pass this to .compare, it uses the same cost and salt. This is why you need a special .compare method rather than just computing the hash on both inputs and comparing the outputs.

Related

How do I recompute web2py's password hash?

I am trying to have another application (running on a different stack) authenticate with an existing application of mine that runs of web2py. I am trying to understand how can I validate the entered password with the one that I have in auth_user?
I did see https://groups.google.com/forum/#!topic/web2py/tLAiqRaXG48 but I was unable to get the has from there. Here is what I am doing:
import hashlib
from pbkdf2 import crypt
crypt(hashlib.sha512("MyPassword").hexdigest(),iterations=1000)
My password in the db reads like this :
pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1
(slightly changed the hash itself)
Any help would be much appreciated.
Thanks,
Rajaram
First, note that the value stored in the password field is not just the final hashed value but includes the algorithm, the per-user salt, and the final hashed value (all delimited by the $ symbol). So, assuming we have:
stored_password = 'pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1'
start by doing something like:
_, salt, hashed_password = stored_password.split('$')
Now, because pbkdf2 was used, we must use hashlib.pbkdf2_hmac to compare the hashes:
from hashlib import pbkdf2_hmac
entered_password = 'MyPassword'
is_match = hashed_password == pbkdf2_hmac('sha512', entered_password, salt,
rounds=1000, dklen=20).encode('hex')
Alternatively, if you don't mind copying the web2py validators.py module to the other system, you can simply do:
from validators import CRYPT
is_match = CRYPT()(entered_password)[0] == stored_password
Note, CRYPT() is a callable object (like all the web2py validators). When you call it with the entered password, it returns a tuple, the first element of which is a LazyCrypt object. The LazyCrypt class has implemented its own __eq__ special method, so the == comparison above triggers that method. It automatically extracts the digest algorithm, salt, and hash from stored_password, computes the hash of entered_password, and compares that to the hash extracted from stored_password (i.e., everything that was done manually in the solution above).

How to decript salt

I'm made one register and loggin form and code.
its ok. I encript my passwords like this:
public static function Hash($password) {
$hash = "f6e649b8fc4c9e35eda6969660e36a2e";
$crypt = md5($password . ($hash));
return $crypt;
}
Why i do to decrypt this?
Thankyou;
This is a very unsafe way to hash a password. The salt is static, so it cannot not fullfill its purpose and MD5 is ways too fast for hashing passwords (one can brute-force about 100 Giga MD5 per second with common hardware).
PHP offers an easy and safe method password_hash() to hash passwords, which handles all the tricky parts like generating a safe salt:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

PBKDF2 with HMAC in Java

I am working on a Java project where I must ensure the confidentiality and integrity of users password saved in a plaintext file.
To do so, I will write only a hash of the password in the file. More specifically, my intention is to write the hash of the password and a random salt, plus the random salt itself, to avoid the use of rainbow and lookup tables. I also want to use key-stretching with PBKDF2, to make the computation of the hash computationally expensive.
Finally, I would like to use a keyed hash algorithm, HMAC, for a final layer of protection.
I am trying to implement my thoughts in a Java code, and I have found some examples of the operations that I have presented above:
private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
throws NoSuchAlgorithmException, InvalidKeySpecException
{
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return skf.generateSecret(spec).getEncoded();
}
The thing that I really cannot understand is how to input my secret key as the key used by the HMAC algorithm, as it doesn't seem an input to the function. I have looked through the Java documentation, but I cannot find a solution to my question.
At this point, I am not really sure if I understood correctly how the different part of the encryption mechanism work, so I would accept any help on the topic.
I think I see the confusion. You're apparently expecting your code to apply PBKDF2 then HMAC-SHA-1. That's not how it works: HMAC-SHA-1 is used inside PBKDF2.
The gist of PBKDF2 is to apply a function repeatedly which has the following properties:
it takes two arguments;
it returns a fixed-size value;
it is practically undistinguishable from a pseudo-random function.
HMAC-SHA-1 is such a function, and a common choice. There are other variants of PBKDF2, using HMAC-MD5, HMAC-SHA-256, or other functions (but these variants aren't in the basic Java library).
PBKDF2 takes two data inputs (plus some configuration inputs): the password, and a salt. If you want to include a secret value in the calculation, PBKDF2's input is the place for it: don't tack on a custom scheme on top of that (doing your own crypto is a recipe for doing it wrong). Append the pepper (secret value common to all accounts) to the salt (public value that varies between accounts).
Note that pepper is of limited usefulness. It's only useful if the hashes and the pepper secret value are stored in different places — for example, if the hashes are in a database and the pepper is in a disk file that is not directly vulnerable to SQL injection attacks.

How can PBKDF2 using HMAC SHA-1 return more than 20 bytes?

If Node's crypto.PBKDF2 uses HMAC SHA-1, how can the key length ever be more than 20 bytes?
Here's what I understand (apparently incorrectly): crypto.PBKDF2(password, salt, iterations, keylen, callback) uses HMAC SHA-1 to hash a password with a salt. Then it takes that hash and hashes it with the same salt. It repeats that for however many iterations you tell it and then passes you back the result. The result is truncated to the number of bytes you specified in keylen.
SHA-1 outputs 160 bits, or 20 bytes. However, I can ask for keylen more than 20 bytes from crypto.PBKDF2, and past the 20th byte, the data doesn't repeat. That doesn't make sense to me.
What am I misunderstanding here?
Try it out:
c.pbkdf2('password', 'salt', 1, 21, function(err, key) {
for (var i = 0; i < key.length; i++) {
console.log(key[i].toString(36));
}
});
I would expect to see some kind of pattern after the 20th byte, but I don't.
To derive the ith block, PBKDF2 runs the full key derivation, with i concatenated to the salt. So to get your 21st byte, it simply runs the derivation again, with a different effective salt, resulting in completely different output. This means deriving 21 bytes is twice as expensive as deriving 20 bytes.
I recommend against using PBKDF2 to derive more than the natural output size/size of the underlying hash. Often this only slows down the defender, and not the attacker.
I'd rather run PBKDF2 once to derive a single master key, and then use HKDF to derive multiple secrets from it. See How to salt PBKDF2, when generating both an AES key and a HMAC key for Encrypt then MAC? on crypto.SE

MD5 Hashing in objective-c (iOS), based on a shared key

I'm currently developing an app which needs to send authentication data with it to a provided API. Basically it needs to generate a hash based on the data you want to send, based on a shared key.
The problem is that while I have been able to track down functions that will do MD5 hashing, they are not based on a key, which is absolutely crucial.
Is there any way this can be done in objective-c for the iOS platform?
The API is usually used with PHP, which provides something like this handy function:
$key = hash_hmac('md5', $postdata , $sharedkey);
Is there any chance of implementing an equal in objective-c?
The MD5 algorithm only uses one string as input. The convention is that you append your key (aka "salt" value) to the string you are hashing. My guess is that the PHP MD5 function has a second parameter for the key to make life easier, but you should get the same result if you just do this:
NSString *value = [data stringByAppendingString:key];
NSString *hashed = MD5HASH(value); //pseudocode
UPDATE:
Okay, I checked Wikipedia and it looks like you need to do a bit of extra work to implement HMAC-style hashing. So you have two options.
Implement the HMAC algorithm on top of the MD5 hash you're already using (it doesn't look too hard - I've pasted the pseudocode below).
Don't bother with HMAC - just generate the hash at both ends using a regular MD5 by concatenating the message and the key - that should be pretty secure, it's what most people do.
HMAC algorithm
function hmac (key, message)
if (length(key) > blocksize) then
key = hash(key) // keys longer than blocksize are shortened
end if
if (length(key) < blocksize) then
key = key ∥ [0x00 * (blocksize - length(key))] // keys shorter than blocksize are zero-padded ('∥' is concatenation)
end if
o_key_pad = [0x5c * blocksize] ⊕ key // Where blocksize is that of the underlying hash function
i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR)
return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) // Where '∥' is concatenation
end function
Typically you just append the key to the bytes that you are hashing.
So if the shared secret is "12345" and you are passing username=jsd and password=test you would construct your string like "username=jsd&password=test&secret=12345". Then the receiving end would construct its own version from the username & password + the secret, run the same md5, and receive the same value.