I have a database with thousands of md5 encrypted passwords and I need to migrate to sha256. What is the safest way to do this by keeping the old passwords with md5 access and the new one with sha256 encryption? Thanks.
Alternatively to creating a new column for the sha256 you can use the existing column for both. Because sha256 hashes are much longer than md5 hashes you can detect the hash algorithm by looking at the length of the hash.
If possible, use PBKDF2 or bcrypt. Plain SHA-2 is too fast.
If you can't use either of them, then you should at least iterate SHA-256 a couple of thousand times to slow down a password guessing attack:
var hash = SHA256(SHA256(salt)+password)
for(int i=0; i<10000; i++)
hash = SHA256(hash);
return hash;
Remember that every user needs to have a different salt, which is usually stored alongside the password hash. A per-application salt is not enough.
For upgrading I'd use the old hash as input to the new function. That way existing hashes gain most of the security increase of the upgrade without requiring the user to login. Don't keep the old MD5 hashes around.
Then on the first login of each user, upgrade his hash to a clean new hash that doesn't use MD5 anymore.
I'd add a new column for the sha256 hash. That way you can just check the new column for null on login and save the new hash when you have access to the plaintext password.
Related
I need to store password in Database. I m on windows and the only algorithm given by that platform is pbkdf2 (as far as I know). So is it OK so store my password as hash of pbkdf2? Or is their a better algorithm available via Windows API (Cryptography API or similar api available on Windows?). I also learn that PBKDF2+SHA512 is not so different than BCrypt
PBKDF2 is indeed a password hash and therefore designed for this kind of operation. That doesn't mean it doesn't have any drawbacks. As usual it has a salt and work factor (a more generic term than iteration count that PBKDF2 uses).
However it doesn't provide any memory hardness, so it is easier to create specialized hardware to attack it. Furthermore, a smart implementation can speedup the HMAC algorithm that is used for the designated hash function by performing pre-calculation. And finally it is super inefficient if you ask more bits than the output of the hash function - but that's not really a topic if you just use it as a password hash instead of (multi-)key derivation.
So PBKDF2 is old, but it is still a million times better than the idiotic amounts of hash(pasword) or hash(salt | password) schemes out there without salt and/or work factor. Literally, because you'd at least use a 1000000 as iteration count.
Note that using a password hash still allows for weak passwords; you should always add additional measures where possible, e.g. password guess limitations, password strength indicators and whatnot. It is mainly useful to protect your users passwords in case the login DB gets stolen.
I need to encrypt file and directory names/paths but I need the encryption to be deterministic. I need to sync the local files with a cloud storage provider so I can't use probabilistic encryption.
Know that you should not use a static IV when encrypting text, would this be an acceptable work around:
Run passphrase through scrypt and store resulting output
Take the resulting output from scrypt and hash it (using MD5 for example)
Take the first 16 bytes of the hash and use it as the IV to encrypt the directory and file name
The only other thing I can think of:
Use probabilistic encryption
Read the directory/file structure from the cloud service provider and local directory
Map all the encrypted cloud provider names with their decrypted values
Map all the encrypted local names with their decrypted values
Sync based on the mappings found above
The only issue with that is that it is time consuming and really difficult to implement when using different cloud service providers.
In order to securely encrypt data, you need to use a different key/IV pair for each message. If you don't, you leak a lot of information about the encryption and it becomes very weak. However, it's not too difficult to do if you have an incrementing counter that never repeats:
Generate a random salt (32 bytes) and store it with the rest of the data. This is public.
Take the current version of the counter as a 32-bit or 64-bit integer.
Use scrypt with your passphrase, and for the salt, concatenate your salt and the counter. Take enough bytes out for both a key and an IV.
Encrypt your file or directory name (ideally with an AEAD if possible, such as AES-GCM or ChaCha20-Poly1305) using the key and IV you've generated. Prepend the counter as an integer.
Increment the counter and store the new counter.
Using a key derivation function like scrypt to generate both the key and IV is secure as long as your use a different salt each time. By generating a random salt, which can be used for your entire project, and then appending a counter, you're producing salts that are both distinct and different from those used by others. Using just the counter wouldn't be distinct enough.
Your proposed idea will use the same key/IV pair for each file name encryption, which would be weak. It doesn't matter how you generate that same key/IV pair, using the same one would remain weak. You must also never reuse the counter in my proposal above, because otherwise you generate the same key/IV pair from scrypt. You can reuse the same counter if you change the random salt, though.
As a note, you should avoid using MD5 for any reason. SHA-256 or BLAKE2b are better choices in all situations.
I need to encrypt the password the user enters in a text box on the UI, save it, and then decrypt it when the getPassword() method is called.
What is the correct JDK 1.4 API I should use?
Thanks in advance.
If you want to secure you passwords, you'll may want to use a Hash algorithm like MD5 or SHA1. You don't want to decrypt the stored password to compare it with the one provided on a login but rather hash the provided password and compare the Hashs
here some documentation on the methods you can use to hash :
https://www.owasp.org/index.php/Hashing_Java
There's an example here using Java 1.4 Crypto interface for MD5 encryption:
http://download.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#HmacEx
Blowfish:
http://download.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#BlowKeyEx
Just use Cipher with the "AES/CBC/PKCS5Padding" mechanism (in getInstance()). You can use a 128 bit (16 byte) AES key created using SecretKeySpec (this is already a key!). Higher bitrates will require unlimited encryption policy files to be installed. As I noted as remark, please note that this is only obscuring the data, since the key will need to be stored with the application - so people that know what to do can retrieve both the password and key and decrypt the information outside of the application.
If you store multiple passwords with the same key, make sure you generate and store a separate random IV per password. The advise in this last paragraph is more to let you know how to encrypt stuff correctly since it is easier to obtain the key than to decrypt the data without it anyway.
I start with a weak password (8 lower case characters for ex) and a file. I need to encrypt that file using that password. Result has to be secure against known attacks.
Approach 1: I could hash the password using SHA-256 and then use the resulting hash and file as inputs to AES-256, giving me an encrypted file. I understand that both SHA-256 and AES-256 are very fast. Wouldn't this make the file vulnerable to a brute force attack?
For example, could one grab a rainbow table of pre-computed SHA-256 hashes and, assuming its a really small file and a really weak password, try to AES-256 decrypt using each hash from that table in a reasonable time (a few months with specialized hardware).
Approach 2: Use bcrypt. If I understand correctly, bcrypt is better suited for encrypting files than SHA-256 + AES-256, since it's key generation scheme has a work factor resulting in a stronger key. Or am I wrong?
The Ruby and Python implementations (wrappers?) that I've seen focus on using bcrypt as a hashing scheme for passwords, not a cipher per se. Can I even use bcrypt to hash a weak pass AND encrypt the file in "one step"?
Approach 3: Use bcrypt to hash the pass, use that hash and file as inputs into AES-256, giving me the encrypted file. This takes care of the "key is too fast to generate" problem. (Assuming its a problem.) However, bcrypt hashes are 448-bits long and AES-256 wants a 256-bit key. Naive solution is to simply drop the trailing bits of the hash and use that as the key for AES-256. I would NOT go this route because I don't know enough about cryptography to know what the consequences are.
EDIT: I can't salt the pass, since this is for an offline application. ie. there is no reasonable place to store the salt. I can salt the pass and store the salt unencrypted along with the encrypted file. Salts are almost inherently public/visible if say a database is compromised. Purpose of a salt is to prevent a rainbow table attack. Thanks to Nemo, bellow.
Approach 4: Use PKCS#5 (PBKDF2 for deriving a key from a pass + a cipher of your choice for encryption using that key), preferably somebody else's implementation.
And don't forget the salt. (You store it together with the encrypted data. It only needs to be 8 bytes or so.)
I'm writing a little desktop app that should be able to encrypt a data file and protect it with a password (i.e. one must enter the correct password to decrypt). I want the encrypted data file to be self-contained and portable, so the authentication has to be embedded in the file (or so I assume).
I have a strategy that appears workable and seems logical based on what I know (which is probably just enough to be dangerous), but I have no idea if it's actually a good design or not. So tell me: is this crazy? Is there a better/best way to do it?
Step 1: User enters plain-text password, e.g. "MyDifficultPassword"
Step 2: App hashes the user-password and uses that value as the symmetric key to encrypt/decrypt the data file. e.g. "MyDifficultPassword" --> "HashedUserPwdAndKey".
Step 3: App hashes the hashed value from step 2 and saves the new value in the data file header (i.e. the unencrypted part of the data file) and uses that value to validate the user's password. e.g. "HashedUserPwdAndKey" --> "HashedValueForAuthentication"
Basically I'm extrapolating from the common way to implement web-site passwords (when you're not using OpenID, that is), which is to store the (salted) hash of the user's password in your DB and never save the actual password. But since I use the hashed user password for the symmetric encryption key, I can't use the same value for authentication. So I hash it again, basically treating it just like another password, and save the doubly-hashed value in the data file. That way, I can take the file to another PC and decrypt it by simply entering my password.
So is this design reasonably secure, or hopelessly naive, or somewhere in between? Thanks!
EDIT: clarification and follow-up question re: Salt.
I thought the salt had to be kept secret to be useful, but your answers and links imply this is not the case. For example, this spec linked by erickson (below) says:
Thus, password-based key derivation as defined here is a function of a password, a salt, and an iteration count, where the latter two quantities need not be kept secret.
Does this mean that I could store the salt value in the same place/file as the hashed key and still be more secure than if I used no salt at all when hashing? How does that work?
A little more context: the encrypted file isn't meant to be shared with or decrypted by others, it's really single-user data. But I'd like to deploy it in a shared environment on computers I don't fully control (e.g. at work) and be able to migrate/move the data by simply copying the file (so I can use it at home, on different workstations, etc.).
Key Generation
I would recommend using a recognized algorithm such as PBKDF2 defined in PKCS #5 version 2.0 to generate a key from your password. It's similar to the algorithm you outline, but is capable of generating longer symmetric keys for use with AES. You should be able to find an open-source library that implements PBE key generators for different algorithms.
File Format
You might also consider using the Cryptographic Message Syntax as a format for your file. This will require some study on your part, but again there are existing libraries to use, and it opens up the possibility of inter-operating more smoothly with other software, like S/MIME-enabled mail clients.
Password Validation
Regarding your desire to store a hash of the password, if you use PBKDF2 to generate the key, you could use a standard password hashing algorithm (big salt, a thousand rounds of hashing) for that, and get different values.
Alternatively, you could compute a MAC on the content. A hash collision on a password is more likely to be useful to an attacker; a hash collision on the content is likely to be worthless. But it would serve to let a legitimate recipient know that the wrong password was used for decryption.
Cryptographic Salt
Salt helps to thwart pre-computed dictionary attacks.
Suppose an attacker has a list of likely passwords. He can hash each and compare it to the hash of his victim's password, and see if it matches. If the list is large, this could take a long time. He doesn't want spend that much time on his next target, so he records the result in a "dictionary" where a hash points to its corresponding input. If the list of passwords is very, very long, he can use techniques like a Rainbow Table to save some space.
However, suppose his next target salted their password. Even if the attacker knows what the salt is, his precomputed table is worthless—the salt changes the hash resulting from each password. He has to re-hash all of the passwords in his list, affixing the target's salt to the input. Every different salt requires a different dictionary, and if enough salts are used, the attacker won't have room to store dictionaries for them all. Trading space to save time is no longer an option; the attacker must fall back to hashing each password in his list for each target he wants to attack.
So, it's not necessary to keep the salt secret. Ensuring that the attacker doesn't have a pre-computed dictionary corresponding to that particular salt is sufficient.
As Niyaz said, the approach sounds reasonable if you use a quality implementation of strong algorithms, like SHA-265 and AES for hashing and encryption. Additionally I would recommend using a Salt to reduce the possibility to create a dictionary of all password hashes.
Of course, reading Bruce Schneier's Applied Cryptography is never wrong either.
If you are using a strong hash algorithm (SHA-2) and a strong Encryption algorithm (AES), you will do fine with this approach.
Why not use a compression library that supports password-protected files? I've used a password-protected zip file containing XML content in the past :}
Is there really need to save the hashed password into the file. Can't you just use the password (or hashed password) with some salt and then encrypt the file with it. When decrypting just try to decrypt the file with the password + salt. If user gives wrong password the decrypted file isn't correct.
Only drawbacks I can think is if the user accidentally enters wrong password and the decryption is slow, he has to wait to try again. And of course if password is forgotten there's no way to decrypt the file.