1) In the context of bcrypt, does a particular saltRound generate a unique salt?
2) why is it that we don't need to supply the salt when we compare the 'plaintextpassword' with the 'hash'ed password as is the case in the following example:
Example from [https://www.npmjs.com/package/bcrypt][1]
bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
// res == true
});
Usually BCrypt implementations generate a unique salt on their own and include it plaintext in the resulting hash-text. The compare function can extract it from there and use the same salt to calculate a comparable hash.
So no, the salt has nothing to do with rounds, and the compare function extracts it from the stored hash. See this answer, explaining the hash format.
Related
I am having trouble understanding the following code from the golang crypto bcrypt repo
func newFromHash(hashedSecret []byte) (*hashed, error) {
if len(hashedSecret) < minHashSize {
return nil, ErrHashTooShort
}
p := new(hashed)
n, err := p.decodeVersion(hashedSecret)
if err != nil {
return nil, err
}
hashedSecret = hashedSecret[n:]
n, err = p.decodeCost(hashedSecret)
if err != nil {
return nil, err
}
hashedSecret = hashedSecret[n:]
// The "+2" is here because we'll have to append at most 2 '=' to the salt
// when base64 decoding it in expensiveBlowfishSetup().
p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
copy(p.salt, hashedSecret[:encodedSaltSize])
hashedSecret = hashedSecret[encodedSaltSize:]
p.hash = make([]byte, len(hashedSecret))
copy(p.hash, hashedSecret)
return p, nil
}
From my understanding salting is used to prevent adversaries that have hack into the database and obtain a list of hashed passwords, to obtain the original password from the hash, hackers can go through all valid password combinations and hash each one of them, if one of the generated hash match with the hash in the hack DB the hacker can get the password back. Adding a salt before hash force the adversary to regenerate the rainbow table.
The key is to hash the password along with the salt
hash(password + salt)
forcing the hacker to regenerate a rainbow table specifically for the salt
But it seems like bcrypt is able to get the salt back, so technically if an adversary knows a system is using bcrypt he can delete the salt and get the hash password that is not salted.
In another word once the hacker get hashedSecret = hashedSecret[encodedSaltSize:] he can use rainbow attack to get the password back making the salt useless.
Am I getting something wrong?
he can delete the salt and get the hash password that is not salted.
Everything except this part is right.
Imagine, you have a password pass and two salts: s1, s2.
hash(s1 + pass) = 123
hash(s2 + pass) = 456
So you would have two stored records in your DB:
s1$123
s2$456
Deleting the salt part won't get the adversary anywhere as he would still have two different hash digests 123 and 456 to crack.
On the other hand, it would render yourself unable to reconstruct your hash once you get cleartext from your user.
Imagine them sending you pass. What you want to do is to get the salt substring from their hash stored in your DB, e.g. s2$456, then concatenate it with the cleartext and then compare hash(s2 + pass) with 456 above. Without having your salt stored in the database you can't do this, that's why it is necessary.
You can get back the salt but that doesn't mean you get the unsalted password hash. "In another word once the hacker get hashedSecret = hashedSecret[encodedSaltSize:] he can use rainbow attack to get the password back making the salt useless." is misleading. The attacker can get the salt and the hashed password but this doesn't allow a "rainbow attack".
The attack in "rainbow attack" is: Generate a huge rainbow-table once, upfront. The list is a pair of (cleartextpassword,passwordhash) entries. Generating this table is very timeconsuming (and might become large if you include lots of passwords and huge if you include all passwords!). The attack in a "rainbow attack" is: You have to generate this rainbow table only once and can use it to look up cleartext passwords for millions of password-hashes very fast.
As each password in the bcrypt code above gets its own salt you cannot use one rainbow table: You would have to create one rainbow table for each salt. Rendering the "rainbow attack" useless.
I was working interchangeably with Node's crypto library and Ruby's OpenSSL library.
The challenge I was coming across was that I could encrypt usingaes256 in both libraries.
However, in node using the crypto.createDecipher('aes256', key) I could have a key that was less than 32 bits long, but ruby would throw an error saying the key is not long enough when using:
cipher = OpenSSL::Cipher.new 'aes256'
cipher.encrypt
key = 'geeses'
I also don't have to set an initialization vector for node, but ruby seems to set one under the covers. I'm pretty new to this crypto stuff, what's going on here?
While #mscdex answers is perfectly, I want to add how to get a cipher with a specific key when your algorithm does not require Initialization Vector using the crypto.createCipheriv or crypto.createDecipheriv
Taking the case of AES-256-ECB where chaining is not done and hence IV is not used.
You can pass empty Buffer as IV.
var data = "plaintext";
const key = crypto.randomBytes(32);
var iv = new Buffer('');
var cipher = crypto.createCipheriv('AES-256-ECB',key,iv);
var encrypted = cipher.update(data,'utf8','base64');
encrypted += cipheriv.final('base64');
console.log('encrypted AES-256-ECB',encrypted);
And decrypt fairly simply using the same pattern:
var decipheriv = crypto.createDecipheriv('AES-256-ECB',key,iv);
var decryptediv = decipheriv.update(encrypted,'base64','utf8');
decryptediv += decipheriv.final('utf8');
console.log('decrypted base64 aes-256 ',decryptediv);
When you use crypto.createDecipher(), the value you pass as the second argument is a password from which a key and IV will be derived (using one iteration of MD5 hashing). This is accomplished by using EVP_BytesToKey() to create those two values. OpenSSL knows the correct lengths both values need to be because the cipher is also passed to EVP_BytesToKey().
So most likely the Ruby function is more analogous to node's crypto.createDecipheriv() which accepts both a key and an IV (which need to be the right lengths for the cipher).
Imagine you have an MD5 sum that was calculated from an array of N 64-byte elements. I want to replace an element at an arbitrary index in the source array with a new element. Then, instead of recalculating the MD5 sum by re-running it through an MD5 function, I would like to "subtract" the old element from the result and "add" the new piece of data to it.
To be a bit more clear, here's some pseudo-Scala:
class Block {
var summary: MD5Result
// The key reason behind this question is that the elements might not be
// loaded. With a large array, it can get expensive to load everything just to
// update a single thing.
var data: Array[Option[Element]]
def replaceElement(block: Block, index: Integer, newElement: Element) = {
// we can know the element that we're replacing
val oldElement = block.data(index) match {
case Some(x) => x
case None => loadData(index) // <- this is expensive
}
// update the MD5 using this magic function
summary = replaceMD5(summary, index, oldElement, newElement)
}
}
Is replaceMD5 implementable? While all signs point to "this is breaking a (weak) cryptographic hash," the actual MD5 algorithm seems to support doing this (but I might be missing something obvious).
I think I better understand what you want to do now. My solution below assumes nothing about MD5 computation, but involves a tradeoff between IO and storing a large number of MD5 hashes. Instead of computing the simple MD5 hash of the entire dataset, it computes a different MD5 hash that nevertheless should have the same important property: that any change to any element (drastically) changes it.
At the outset, decide on a block size b such that
you can afford to read b values from disk (or whatever IO you're talking about) per change of element, and
you can afford to keep 2n/b MD5 hashes in memory.
Create a binary tree of MD5 hashes. Each leaf in this tree will be the MD5 hash of a size-b block. Each internal node is the MD5 hash of its two children. We will use the hash of the root of this tree as "the" MD5 hash.
When element i changes, read in the b elements in block RoundDown(i/b), compute the new MD5 hash for this, and then propagate the changes up the tree (this will take at most log2(n) steps).
Given a hashmap in Golang which has a key and a value, what is the simplest way of retrieving the key given the value?
For example Ruby equivalent would be
key = hashMap.key(value)
There is no built-in function to do this; you will have to make your own. Below is an example function that will work for map[string]int, which you can adapt for other map types:
func mapkey(m map[string]int, value int) (key string, ok bool) {
for k, v := range m {
if v == value {
key = k
ok = true
return
}
}
return
}
Usage:
key, ok := mapkey(hashMap, value)
if !ok {
panic("value does not exist in map")
}
The important question is: How many times will you have to look up the value?
If you only need to do it once, then you can iterate over the key, value pairs and keep the key (or keys) that match the value.
If you have to do the look up often, then I would suggest you make another map that has key, values reversed (assuming all keys map to unique values), and use that for look up.
I am in the midst of working on a server based on bitcoin and there is a list of constants and byte codes for the payment scripts. In the C++ version it has both identifiers with the codes and then another function that returns the string version. So it's really not much extra work to just take the original, with opcodes as string keys and the byte as value, and then reverse the order. The only thing that niggles me is duplicate keys on values. But since those are just true and false, overlapping zero and one, all of the first index of the string slice are the numbers and opcodes, and the truth values are the second index.
To iterate the list every time to identify the script command to execute would cost on average 50% of the map elements being tested. It's much simpler to just have a reverse lookup table. Executing the scripts has to be done maybe up to as much as 10,000 times on a full block so it makes no sense to save memory and pay instead in processing.
I want to generate a random salt...
I am doing this but get the same salt every time even if I restart my program .. i checked using println
SecureRandom random = SecureRandom.getInstance("NativePRNGBlocking");
byte[] salt = new byte[32];
random.nextBytes(salt);
System.out.println(salt);
return salt;
How to generate a random salt? I want a separate salt for each user.
The bytes in the salt array will in fact be different, at least unless the NativePRNGBlocking implementation is broken. I think the problem is in your check. The toString method for byte arrays does not print the values in the array, so printing the salt array in that way is useless. Try to print the individual values:
for(byte b: salt) {
System.out.print(b + " ");
}
Or you could just inspect them in a debugger.
SecureRandom class supports the “SHA1PRNG” pseudo random number generator algorithm.
Try the below code it works fine for me and getting always unique outptut.
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
//Create array for salt
byte[] salt = new byte[32];
//Get a random salt
sr.nextBytes(salt);
//return salt
System.out.println( salt.toString());
Hope it will resolve your issue.