Let's say I encrypt my passwords with PBKDF2 and store it somewhere. Now let's say it was stolen and the hacker, who stole it knows it was hashed with PBKDF2.
Does a knowledge of number of iterations make it easier to brute force the password?
Moved my question to relevant stackexchange:
https://crypto.stackexchange.com/questions/60860/should-number-of-iterations-of-pbkdf2-stay-secret
Related question:
https://crypto.stackexchange.com/questions/25595/is-there-a-tangible-benefit-in-keeping-the-number-of-pbkdf-iterations-secret-and
Related
I'm experimenting with PBKDF2 for my passwords right now, and it dawned on me that if I were to ever upgrade to a faster machine in the future, I would want to increase the number of PBKDF2 iterations. However, this would invalidate all the current passwords that I have stored. One idea I've seen was to store the PBKDF2 settings along with the password (similar to how you store the salt) such as the iteration count and the PRF used (SHA-256, SHA-512) at the time of the hash creation. It sounds like a good idea in terms of backwards compatibility, but I wanted to know if there are any drawbacks to doing this. Any insight into this would be appreciated.
You are definitely taking the right direction here. Many systems store just the salt but where is the rest of the parameters required to perform PBKDF2? Hardcoded! And hardcoding parameters of cryptographic functions is almost never a good idea.
Only drawback I see is that when you store all the parameters your database will probably take a little more space but your future upgrades will be much easier and straightforward.
BTW RFC 2898 defines structure called PBKDF2-params which was designed as a data holder for all the public parameters of PBKDF2 algorithm. Use it at least as an inspiration so you won't forget any important parameter.
As there have been significant advances in the cryptoanalysis of SHA1 it's supposed to be phased out in favor of SHA2 (wikipedia).
For use as underlying hash function in PBKDF2, however, it's basically used as a PRNG. As such it should be still secure to use SHA1 as hash for PBKDF2, right?
None of the currently known weaknesses on SHA-1 has any impact on its security when used in HMAC, a fortiori when used in PBKDF2. For that matter, MD5 would be fine too (but not MD4).
However, SHA-1 is not good for public relations: if, in 2011, you use SHA-1, then you must prepare yourself to have to justify that choice. On the other hand, SHA-256 is a fine "default function" and nobody will question it.
There is no performance issue in PBKDF2 (PBKDF2 includes an "iteration count" meant to make it exactly as slow as needed) so there is very little reason to prefer SHA-1 over SHA-256 here. However, if you have an existing, deployed system which uses PBKDF2-with-SHA-1, then there is no immediate need to "fix" it.
Sure. SHA-256, or larger, might be more efficient if you want to generate more key material.
But PBKDF2-HMAC-SHA1 is fine. Also standard HMAC use has not been compromised, but again, longer hashes are in principle more secure in that scenario.
The attacks on SHA1 which caused a lot of public turmoil make it possible to construct a message which has the same hash as a different message. This is of course always possible (in principle) for every hash function, since a hash function has fewer output bits than input bits. However, it is normally not likely to happen by accident, and doing it on purpose should be computationally not feasible.
From a "ensure message integrity" point of view, this can be seen as a disaster.
On the other hand, for the purpose of generating random numbers, this has absolutely no bearing.
Say I have some data and a password, and I want to encrypt the data in such a way that it can only be recovered with the right password.
How does this technically work (i.e. how to implement this)? I often hear people use bitshifting for encryption, but how do you base that on a password? How does password-based encryption work?
An example is Mac OS X FileVault
Thanks.
If you give sample code, preferably in C, Objective-C or pseudocode.
For (symmetric) encryption you need a secret key for encryption and decryption.
Usually, the password you supply is used as the source of this key. For various security reasons, the password is not (and often cannot, due to requirements of the cipher used) directly used as the key. Instead, a key derivation function is used to generate the key from the password.
This is why passwords for encryption must be long and fairly random: Otherwise the resulting key will only come from a very small subset of possible keys, and these can then simply all be tried, thus brute-forcing the encryption.
As to code examples, there are several possibilities:
look at the source code of a crypto library, such as OpenSSL
look at the source code of a program that implements encryption, such as GnuPG
google some sample source code for a simple encryption algorithm, or a key derivation function, and try to understand it
This depends on what you want to learn.
You'll need to look to other resources for a deep explanation, as this question is extremely broad.
Speaking generally: you use a password as a "seed" for an encryption key, as sleske pointed out. Then you use this key to apply a two-way encryption algorithm (i.e. one that can be applied once to encrypt and again to decrypt). When you apply the algorithm to a piece of data, it becomes encrypted in such a way that you could never get the data back out again without using the same key, and you can't practically produce the same key without having the same password as a seed.
If you're interested in crypto, read Applied Cryptography by Bruce Schneier. Excellent read, lots of examples. It goes through many different cryptography types.
An easy way, but not exactly secure, is to rotate each byte by a number determined by the password. You can use a hash code from a string, or count the number of characters, or whatever for the number.
What you are probably thinking of, though, is public key encryption. Here is a link to a document that will tell you the math for it - you'll have to work out the implementation details yourself, but it's not that hard once you understand the math.
http://mathaware.org/mam/06/Kaliski.pdf
The basic building block of most block ciphers is a construction called a Feistel Network. It's reasonably easy to understand.
Stream ciphers are even simpler - they're essentially just pseudo-random number generators, albeit with some important security properties, where the initial internal state is derived from the key.
Password based encryption IS symmetric. The input usually consists of a salt in addition to the password. FooBabel has a cool app where you can play around with this... currently they hard code the Salt to an array of eight bytes (zero to seven) for simplicity. I put in a request to see that they let users input the salt. Anyway, here it is - PBECrypto
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
My PGP secret keys are always password protected, which means you need to decrypt it using a symmetric key to get access to my private key.
I am interested in making my password protected PGP secret key publicly available but I am not entirely sure if I am missing something. Storing my secret key on my computer seems only to be making things harder (security through obfuscation) but not actually doing any good.
considering that i can password protect my private key with a 256 bit AES
http://en.wikipedia.org/wiki/Key_size#Symmetric_algorithm_key_lengths
and that there is theoretical limit for the energy needed to crack a 2^n password using brute force
http://en.wikipedia.org/wiki/Brute_force_attack#Theoretical_limits
What am I missing?
It decreasing your cryptographic strength a lot as brute force attacks to decrypt it could succeed in a shorter time. Typically passwords have not so many bits than the key itself. Unless your password is more than 20 chars I would strongly advise not to do so. Short passwords can be cracked rather quickly.
I was going to show you all the math to tell you why you shouldn't make your encrypted private key public, but that was too long to read and too complicated. Here is a simple answer.
You use asymmetric algorithms so that you don't have to rely only on your password! Your password is weak. The asymmetric algorithm is much stronger. If you expose your private key, even if it is encrypted with a password, then you are preventing it from being able to properly serve its purpose.
If you expose your private key, it is good to know that the length of the key itself will not matter as much as the length and randomness of the password you are using to protect it.
Why would you like to expose your private key to the public (even if it is password protected?)
No you wouldn't want to leave your private key lying around. If they had access to your private key there is always the risk that they could brute force your passphrase or obtain it through eavesdropping on keyboard sounds, key logger, tempest emissions attack, sticking your kid's finder in a light socket... If they don't have access to your private key then they might as well give up, nothing they do or you do is going to get them access to that data.
It's true to say that a proper use of a randomly-generated 256-bit symmetric key with a strong algorithm cannot practically be brute-forced, but as soon as you generate a key from a passphrase - as you typically do with your PGP or GPG private keys - you have violated that assumption. As others have said, it's quite risky. It would be a different matter if you encrypted your private keys under a properly-generated symmetric key and put that key on (say) a USB stick - but then, of course, you have merely pushed the problem sideways and now have a precious USB stick to take care of. If you were really paranoid you might do this but encrypting the symmetric key on the USB stick under a passphrase: then an attacker has to get the stick contents and crack your passphrase in order to steal your private key, which on the face of it is harder than either task alone. But in some cases this is too much hassle...
This is a question about an authentication scheme.
Say I have a shared secret string S, and two computers, C1 and C2
Computer one (C1) sends a random string (R) to computer two (C2)
C2 hashes (say SHA256) the concatenation of S and R (SR)
C2 sends the hash of SR to C1, along with some instructions
C1 compares the received hash of SR with it's own hash of SR and executes the instructions if they match
Wash, rinse, repeat with different values of R
Now, what I want to know is if someone intercepts a whole bunch of R values, and a whole bunch of SR hashes, can they use that as a "crib" to work out what S is, thus allowing them to forge instructions?
I'm already aware of the potential for a MITM attack here (attacker intercepts response, changes the instructions and forwards it on).
I honestly don't know what I'm dealing with here, I only have a bit of historical knowledge about encryption but that included the use of cribs to break them. I'm not a theorist, so anything you can definitively tell me about specific strong hashes would be great.
Alternate authentication schemes are also welcome, assuming the constraints of an existing shared secret string like in this example. Would I be better off just using S as a key for AES? If I do that, can I still use this in the encrypted message to prevent replay attacks?
Any and all advice welcome, I sort of deviated from my question at the end, so feel free to deviate in your answers!
What you're talking about is called a message authentication code - a MAC. If the secret is sufficiently large (such that it cannot be brute forced in reasonable time) and the MAC is properly implemented, then no, knowing the plaintext doesn't help the attacker.
The key, however, is that it has to be properly implemented. The problem is that crypto is hard. Really hard. Unless you're an expert or have an expert to review your work in context, it's extremely easy to make a mistake. Even worse, it's very easy for people to write crypto that they don't know how to break, but which can be broken quite easily by someone in the know.
The advice you got in the comments is the correct advice: use a proven scheme like SSL or TLS instead of creating your own.
Answering your question:
No, the only way to break a hash is brute force, as small diferences in the origin mean big differences in the output of the hashing algorithm (given that the algorithm has been proben to be unbroken). You must to know S to perform a MITM here.
But, Byron Withlock is correct:
Using a homemade encryption scheme when there are sooo many better schemes available is crazy. Leave encryption to the experts. – Byron Whitlock 4 mins ago
I'm with Byron. Just use something off-the-shelf and tested by people with a clue. How about SSL? – Steven Sudit 57 secs ago
Many cryptographic hash functions are vulnerable to a lengt extension attack. That means if an attacker knows hash(S) but not S, then he may still be able to compute hash(S || M) for some messages M. For example, the attacker might try to get hash(S), by sending the challenge string "" to one of the parties. Your scheme does not have a detailed description. So it is not clear if such a length extension attack is possible. To avoid these kind of attacks you might consider to use for example HMAC instead of the more simple hashing scheme that you propose.
This scheme is weak because the instructions themselves aren't authenticated. You want to send the MAC of R + instructions - and ensure that R is fixed length so that an attacker can't shuffle about between R and instructions.
I take it the purpose of the random value is to ensure the "freshness" of the instructions sent?
You could also look into using gpg, if SSL doesn't meet your needs. That's likely to be a lot better than homegrown crypto.