What should be the data type for the hashed value of a password encrypted using PBKDF2? - hash

I am trying to learn to use PBKDF2 hash functions for storing passwords in the database. I have a rough draft of the procedure that I'll be using to generate the hashed function. But while I am creating the table in PL/SQL Developer which will hold the generated hashed password, what should I declare the data type for the encrypted password variable?
It might be a lame question but I'm trying to learn online. It would be a huge help if I can get links for further study as well. thank you. please help

The first link, as always, is Thomas Pornin's canonical answer to How to securely hash passwords.
Storage in the database
The hash can be stored in BINARY format for the least transformations and smallest number of bytes; see below for sizes.
Alternately, store it in a CHAR after converting to hex, which costs a transformation and double the bytes of the BINARY size
Alternatively, store it in a CHAR after converting to Base64, which costs a transformation and 4/3rds the number of bytes of BINARY size plus padding
i.e. PBKDF2-HMAC-SHA-512 where all 64 bytes of output are used would be
BINARY(64) as binary
CHAR(128) as hex
CHAR(88) as Base64
The number of iterations should be stored in an INT, so it can be trivially increased later
The salt, which must be a per-user, cryptographically random value, can be stored in a BINARY format for the smallest number of bytes, and should be at least 12, and preferably 16-24 bytes long.
i.e. for a 16 byte binary salt
BINARY(16) as binary
CHAR(32) as hex
CHAR(24) as Base64
Optionally a password hash algorithm version as a small INT type
i.e. 1 for PBKDF2-HMAC-SHA-512, and then later if you change to BCrypt, 2 for BCrypt, etc.
Normal PBKDF2 considerations
Consider using PBKDF2-HMAC-SHA-512, as SHA-512 in particular has 64-bit operations that reduce the advantage most GPU based attackers have over you as of early 2016.
Use a high (hundreds of thousands or high tens of thousands) of iterations.
Don't ask for a larger number of PBKDF2 output bytes than the native hash function supports
SHA-512 <= 64 bytes
SHA-384 <= 48 bytes
SHA-256 <= 32 bytes
SHA-224 <= 28 bytes
MD5 <= 20 bytes

Related

Compression or encrypt data

I have two bytes and I want to compress them into a single byte using a key( key length can be up to 64 bits).
And further I want to be able to retrieve the two bytes by using the compressed byte and the same key.
Someone has an idea how to do that?
Thanks.
There are 2^{16} = 65,536 ways two choose a pair of 8-bit bytes.
However the result of your procedure is only one 8-bit byte, which can occur in 2^8 = 256 different variations.
So you could use this one byte as input to some decompressing procedure, but because there are only 256 different inputs, the procedure can not produce more than 256 different results, so you can retrieve no more than 256 of the 65,536 possible pairs, the other pairs are not accessible, because you ran out of names for them, so to say.
This makes the procedure impractical, if more than 256 different input byte pairs occur.
(See the comments below for more details)
Compression would only be practical, if restrictions on your input data exist. E.g. if only the pairs p1 = (42,37) and p2 = (127,255) can occur as possible input you could compress them as 01 and and 02.

Crypto - Express.js is PBKDF2 HMAC-SHA1 enough?

Using the Express.js framework and crypto to hash a password with pbkdf2 I read that the default algorithm is HMAC-SHA1 but i dont understand why it hasnt been upgraded to one of the other families or SHA.
crypto.pbkdf2(password, salt, iterations, keylen, callback)
Is the keylen that we provide the variation of the the SHA we want? like SHA-256,512 etc?
Also how does HMAC change the output?
And lastly is it strong enough when SHA1 is broken?
Sorry if i am mixing things up.
Is the keylen that we provide the variation of the the SHA we want? like SHA-256,512 etc?
As you state you're hashing a password in particular, #CodesInChaos is right - keylen (i.e. the length of the output from PBKDF2) would be at most the number of bits of your HMAC's native hash function.
For SHA-1, that's 160 bits (20 bytes)
For SHA-256, that's 256 bits (32 bytes), etc.
The reason for this is that if you ask for a longer hash (keylen) than the hash function supports, the first native length is identical, so an attacker only needs to attack bits. This is the problem 1Password found and fixed when the Hashcat team found it.
Example as a proof:
Here's 22 bytes worth of PBKDF2-HMAC-SHA-1 - that's one native hash size + 2 more bytes (taking a total of 8192 iterations! - the first 4096 iterations generate the first 20 bytes, then we do another 4096 iterations for the set after that!):
pbkdf2 sha1 "password" "salt" 4096 22
4b007901b765489abead49d926f721d065a429c12e46
And here's just getting the first 20 bytes of PBKDF2-HMAC-SHA-1 - i.e. exactly one native hash output size (taking a total of 4096 iterations)
pbkdf2 sha1 "password" "salt" 4096 20
4b007901b765489abead49d926f721d065a429c1
Even if you store 22 bytes of PBKDF2-HMAC-SHA-1, an attacker only needs to compute 20 bytes... which takes about half the time, as to get bytes 21 and 22, another entire set of HMAC values is calculated and then only 2 bytes are kept.
Yes, you're correct; 21 bytes takes twice the time 20 does for PBKDF2-HMAC-SHA-1, and 40 bytes takes just as long as 21 bytes in practical terms. 41 bytes, however, takes three times as long as 20 bytes, since 41/20 is between 2 and 3, exclusive.
Also how does HMAC change the output?
HMAC RFC2104 is a way of keying hash functions, particularly those with weaknesses when you simply concatenate key and text together. HMAC-SHA-1 is SHA-1 used in an HMAC; HMAC-SHA-512 is SHA-512 used in an HMAC.
And lastly is it strong enough when SHA1 is broken?
If you have enough iterations (upper tens of thousands to lower hundreds of thousands or more in 2014) then it should be all right. PBKDF2-HMAC-SHA-512 in particular has an advantage that it does much worse on current graphics cards (i.e. many attackers) than it does on current CPU's (i.e. most defenders).
For the gold standard, see the answer #ThomasPornin gave in Is SHA-1 secure for password storage?, a tiny part of which is "The known attacks on MD4, MD5 and SHA-1 are about collisions, which do not impact preimage resistance. It has been shown that MD4 has a few weaknesses which can be (only theoretically) exploited when trying to break HMAC/MD4, but this does not apply to your problem. The 2106 second preimage attack in the paper by Kesley and Schneier is a generic trade-off which applies only to very long inputs (260 bytes; that's a million terabytes -- notice how 106+60 exceeds 160; that's where you see that the trade-off has nothing magic in it)."
SHA-1 is broken, but it does not mean its unsafe to use; SHA-256 (SHA-2) is more or less for future proofing and long term substitute. Broken only means faster than bruteforce, but no necesarily feasible or practical possible (yet).
See also this answer: https://crypto.stackexchange.com/questions/3690/no-sha-1-collision-yet-sha1-is-broken
A function getting broken often only means that we should start
migrating to other, stronger functions, and not that there is
practical danger yet. Attacks only get stronger, so it's a good idea
to consider alternatives once the first cracks begin to appear.

Is there a limit on the message size for SHA-256?

When hashing a string, like a password, with SHA-256, is there a limit to the length of the string I am hashing? For example, is it only "safe" to hash strings that are smaller than 64 characters?
There is technically a limit, but it's quite large. The padding scheme used for SHA-256 requires that the size of the input (in bits) be expressed as a 64-bit number. Therefore, the maximum size is (264-1)/8 bytes ~= 2'091'752 terabytes.
That renders the limit almost entirely theoretical, not practical.
Most people don't have the storage for nearly that much data anyway, but even if they did, processing it all serially to produce a single hash would take an amount of time most would consider prohibitive.
A quick back-of-the-envelope kind of calculation indicates that even with the fastest enterprise SSDs currently1 listed on Tom's hardware, and striping them 16 wide to improve bandwidth, just reading that quantity of data would still take about 220 years.
1. As of April 2016.
There is no such limit, other than the maximum message size of 264-1 bits. SHA2 is frequently used to generate hashes for executables, which tend to be much larger than a few dozen bytes.
The upper limit is given in the NIST Standard FIPS 180-4. The reason for the upper limit is the padding scheme to countermeasure against the MOV attack that Merkle-Damgard construction's artifact. The message length l is lastly appended to the message during padding.
Then append the 64-bit block that is equal to the number l expressed using a binary representation
Therefore by the NIST standard, the maximum file size can be hashed with SHA-256 is 2^64-1 in bits ( approx 2.305 exabytes - that is close to the lower range of the estimated NSA's data center in UTAH, so you don't need to worry).
NIST enables the hash of the size zero message. Therefore the message length starts from 0 to 2^64-1.
If you need to hash files larger than 2^64-1 then either use SHA-512 which has 2^128-1 limit or use SHA3 which has no limit.

pbkdf2 key length

What is the $key_length in PBKDF2
It says that it will be derived from the input, but I see people using key_lengths of 256 and greater, but when I enter 256 as a key_length the output is 512 characters. Is this intentional? Can I safely use 64 as the key_length so the output is 128 characters long?
$key_length is the number of output bytes that you desire from PBKDF2. (Note that if key_length is more than the number of output bytes of the hash algorithm, the process is repeated twice, slowing down that hashing perhaps more than you desire. SHA256 gives 32 bytes of output, for example, so asking for 33 bytes will take roughly twice as long as asking for 32.)
The doubling of the length that you mention is because the code converts the output bytes to hexadecimal (i.e. 2 characters per 1 byte) unless you specify $raw_output = true. The test vectors included specify $raw_output = false, since hexadecimal is simply easier to work with and post online. Depending on how you are storing the data in your application, you can decide if you want to store the results as hex, base64, or just raw binary data.
In the IETF specification of Password-Based Cryptography Specification Version 2.0 the key length is defined as
"intended length in octets of the derived key, a positive integer, at most
(2^32 - 1) * hLen" Here hLen denotes the length in octets of the pseudorandom function output. For further details on pbkdf2 you can refer How to store passwords securely with PBKDF2

60bit hashing algorithm

Is there a cryptographically secure hashing algorithm which gives a message digest of 60 bits?
I have a unique string (id + timestamp), I need to generate a 60 bit hash from it. What will be the best algorithm to create such a hash?
You can always take a hash algorithm with a larger output size, e.g. sha256, and truncate it to 60 bits. Whether that is appropriate for your needs I cannot say without much more information. 60 bits is generally considered way too short for most security needs.
There is no 60 bit algorithm for encryption. Algorithms are in powers of 2.
I suggest using sha1 to create the hash. It is 128 bit
hash=sha1(id + timestamp)
If you must(not recommended) compress this, use substring to reduce it to 64 bits
smallHash=substr(hash, 0,8)
(8 characters=64 bits)
Any hashing algorithm that has a 60-bit output size can at maximum provide only 30 bits of collision resistance (by the birthday paradox). 30 bits is much too short to be useful in security nowadays.