I'm doing password based file encryption in Java; I'm using AES as the underlying encryption algorithm and PBKDF2WithHmacSHA1 to derive a key from a salt and password combination using the following code (which I got from another generous poster on this site).
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec ks = new PBEKeySpec(password,salt,1024,128);
SecretKey s = f.generateSecret(ks);
Key k = new SecretKeySpec(s.getEncoded(),"AES");
I share the salt, the user enters their password at each end and encryption and decryption work fine :-) My problem is that i would like to be able to verify that the password the user enters is correct before embarking on the (potentially long) decryption process. I know the PBKD spec includes an optional 2 byte verification value but I'm not sure how to generate this value using the above approach. Does Java provide support for this or if not what would be a secure alternative?
Thanks for your time.
There is no "quick check" mechanism that is secure, by definition. The whole point of using PBKDF2 or related techniques is to make password checking slow, to foil password cracking programs. If you added a quick check system, password crackers would be able to guess passwords in bulk very quickly.
Hey, thanks to crazy scot and Chris for there help. After doing some digging i decided to use the methods described on Dr Gladmans file encryption page for doing both password verification and message authentication. I believe this method, based on the PBKDF2 and a MAC, makes deriving the verfication value for m the password sufficiently expensive as to make it secure. Thanks again, and i hope this solution aids others.
Compute some sort of password verification tag and store that alongside the encrypted file data so that you can check it first. This might be something like the PBMAC of a fixed (short) string. Of course, this needs to be a non-reversible function so a cracker could not determine the password, and not be too quick to compute so as to confound the brute force attack.
Have you considered whether (and how) you will detect if the whole file has been decrypted correctly? You should probably look into some combination of PBES2 and PBMAC rather than using AES directly.
Related
Is there a way to decrypt PBKDF2 password in java. Java has implementation of PBKDF2 algorithm as PBKDF2WithHmacSHA1. I got the code to create hashes for password. I referred to below link for hashing technique:
http://howtodoinjava.com/security/how-to-generate-secure-password-hash-md5-sha-pbkdf2-bcrypt-examples/
My requirement is to store the third Party FTP server password in the encrypted format and get back the password in plain text form from DB when there is a need to login into the server. Can anyone suggest best password encryption method?
Note that PBKDF2 is a hashing-method rather than an encryption-method (to be precise: it is a method to derive an encryption-key from a password but it is frequently used as a password-hashing method as well). The whole point of PBKDF2 is to make it impossible to get the original password other than by brute-force guessing and make that as hard as possible too.
If you are talking about your users' passwords: you should not be able to get them in clear at all - if you did and let me know (e.g. by showing me my password) I'd instantly mark your whole site as insecure.
If you need to keep an encrypted password for your application to access another service then PBKDF2 is the wrong tool for the job, use a real encryption-algorithm like AES instead.
No it's impossible by design! Wonder why?
Following 2 articles will answer all your questions:
https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/
https://crackstation.net/hashing-security.htm
I want to obfuscate(*) some passwords to hide them in Java source code.
Discovering jasypt I thought I encrypt the password text beforehand and then decrypt in the source code from the remembered seed + encrypted password. However, the encryption process does not seem to be reproducible: When generating an encrypted password text with
BasicTextEncryptor bte = new BasicTextEncryptor();
bte.setPassword("something"); // the "seed"
String ep = bte.encrypt("mypasswordtext")
I get in ep always different encrypted passwords back every time I run it: For example Zx5RdBLxIB1sPxG7Os3/G4aqqfy59l8n, v3-D3AZWJAybdqWac9FsjdLgMqkAS9vS or ghsD3wZwJAwjk9ghqwFLwqwgMqkwS9vS.
How can I make the encryption reproducible, so that I can use the seed plus encrypted string to generate the real password?
(*) I use "obfuscate", because I know that this isn't a secure way to hide a password at all, but at least it helps that people cannot spot the passwords just by glaning at the source code, while keeping it all contained in the source code file.
The BasicTextEncryptor will generate a random salt every time you perform an encryption and include it in the output, as you can see here: http://www.jasypt.org/api/jasypt/1.9.0/org/jasypt/encryption/pbe/StandardPBEStringEncryptor.html#encrypt(java.lang.String). Decryption should still work even though the ciphertexts are not the same.
If you wanted to produce the same result every time, you'd have to directly set up and configure a StandardPBEStringEncryptor with a non-random salt generator.
However, it would not be good practice to do either of these things, as you mention at the end of your post. If you're working on a "real-world" application, you should avoid storing these secrets in the source code at all.
Is there a way to decrypt PBKDF2 password in java. Java has implementation of PBKDF2 algorithm as PBKDF2WithHmacSHA1. I got the code to create hashes for password. I referred to below link for hashing technique:
http://howtodoinjava.com/security/how-to-generate-secure-password-hash-md5-sha-pbkdf2-bcrypt-examples/
My requirement is to store the third Party FTP server password in the encrypted format and get back the password in plain text form from DB when there is a need to login into the server. Can anyone suggest best password encryption method?
Note that PBKDF2 is a hashing-method rather than an encryption-method (to be precise: it is a method to derive an encryption-key from a password but it is frequently used as a password-hashing method as well). The whole point of PBKDF2 is to make it impossible to get the original password other than by brute-force guessing and make that as hard as possible too.
If you are talking about your users' passwords: you should not be able to get them in clear at all - if you did and let me know (e.g. by showing me my password) I'd instantly mark your whole site as insecure.
If you need to keep an encrypted password for your application to access another service then PBKDF2 is the wrong tool for the job, use a real encryption-algorithm like AES instead.
No it's impossible by design! Wonder why?
Following 2 articles will answer all your questions:
https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/
https://crackstation.net/hashing-security.htm
Does anyone know good tutorials to change PBEWithMD5AndDES encryption algorithm to AES for a Java application? Specially , I want to know what precautions I should take while changing this algorithm to more secure one. Any important test cases to check before and after algorithm changes. Another question is since I have used PBEWithMD5AndDES , most of the user passwords are encrypted using that algorithm. So if I change my algorithm to AES , how do I make sure that decryption of passwords happen with old algorithm while I can still use new algorithm for any new encryption.
Normally you wouldn't encrypt a users password, you'd just hash it with a salt instead.
Migrating from one encryption system to another is going to be a bit of a pain, as I see it you have two options:
During the upgrade process decrypt then re-encrypt all the passwords
Add a flag indicating the encryption method used. All existing passwords will obviously be set to the current standard. New users will be set to whatever method you choose and you can migrate other users when they change their password.
If you've already got data encrypted in format a, and you want to start using another encryption scheme, b, I can think of two ways to accomplish this:
Decrypt all of your data and re-encrypt it using `b`. This approach would be good when you can take your data store offline and "fix everything at once."
For each item you attempt to decrypt, try to decrypt it using `b` first. If that fails, decrypt it using `a`. The next time you try to encrypt something, make sure you use `b`. This approach could be used when you can't take your data store offline, but you want to encrypt all of your data using another algorithm. All of your data will eventually be encrypted using the other algorithm.
There's really no problem changing algorithms. What you need to do is decrypt the cipher text and then encrypt the resulting plain text with the new algorithm. That's straightforward. If you are going to perform this transition over time, I would suggest creating a new database table that keeps track of whether a particular entity (based on unique id) has been transfered to the new algorithm. If it has, then you simply use the new algorithm to decrypt it and you can forget about it, if not, then you use the old algorithm to decrypt it. Regardless though, all new encryption should be performed with the new algorithm.
Now, there's a second issue here. Why are you bothering to decrypt passwords? Just save the hash of the password and forget about it. If you are able to decrypt passwords, you introduce a potential vulnerability. If a malicious user can get a hold of your key you use to encrypt those passwords, then they could access the plain text of the password. Not only could the user then use that information to compromise your system, if your users use the same username/password combination for other sites, those accounts would be compromised as well. You should only store a hash of the password (SHA is a good one, don't use MD5) and then when the user attempts to log in, you hash the input and compare the two results. You have no need to know what the plain text password is.
you may look into ESAPI - java http://code.google.com/p/owasp-esapi-java/
ESAPI 1.4 was using PBEWithMD5AndDES, but in 2.0 they introduced AES
check their mail chain here
you may check the difference between the two implementations
PBEWithMD5AndDES is a method of taking a user's password and from it deriving an encryption scheme that can be used to protect further data. It is not a method of verifying a password, nor of encrypting one.
If you are only interested in password validation, then decrypt the passwords and replace them with a secure hash and in future match the hashes. You will also need your password reminder service to a password reset service.
The question is where is the password you are passing into the PBE algorithm coming from? If it is a fixed password for your application, then you just need to replace it and perform some kind of rolling upgrade. As an observation, if you are storing encrypted data as text, either hex or base-64 encoded, there are characters that cannot appear in the text output and which you can hence prepend to indicate a newer encryption scheme. For example the : character does not appear in base-64. That will allow you to identify what has been upgraded and what has not.
If the passwords are coming from the user, then each user has their own password derived cipher. In this case you can only re-encrypt whatever data has been encrypted with the user's cipher when the user provides their password.
The most direct replacement is going to be along the lines of PBEWithSHA256And256BitAES. Unfortunately, this is not supported by Java 6, so you will need a 3rd party JCE library such as Bouncy Castle. Bouncy Castle offers PBEWithSHA256And256BitAES-CBC-BC, which would be a suitable replacement.
The process of upgrading the cipher is a challenge. Whatever data has been encrypted with DES can only be decrypted with the user's password. I assume you do not have access to the passwords. This means you can only re-encrypt the data when the person who knows the password provides it. You are going to have a long period of time when your system contains a mixture of ciphers, so you need a way of identifying what is converted.
If we are talking about files, you could change the file suffix, or the folder they are stored in. If we are talking about BLOBs in a database, you could add an extra column to the database table to say what the encryption method is. If neither of those are possible you could add some form of header to the data to indicate that it has been encrypted in a new way. That's slightly risky as your existing data has no header and there is an outside chance it will match the new header by accident.
It may also be advisable to keep a list of which users have not yet had their data converted so you can prompt them to convert.
I am using Postgresql,hibernate and Java and I need to store a password. Can someone suggest me how to encrypt the password with md5. Else is there a better way to store secure password in the database
Thanks
You shouldn't use md5 for password hashing. It's built for speed which makes it easier to attack. Use bcrypt instead. Also, you're not supposed to try to decrypt the password after it has been stored. See the examples on the bcrypt page for how to verify a password from user input. More information on how to store passwords safely.
jBcrypt is real simple to use too. Here's how you hash a password:
BCrypt.hashpw(password_from_user, BCrypt.gensalt());
And to verify it:
BCrypt.checkpw(password_from_user, hashed_password_from_database)
MD5 isn't an encryption algorithm - it is a cryptographic hash function. This is very different! You can store the hashed password in the database, but you cannot (in general) recover the password from the password's hash. This is by design.
In some cases it is possible to get the password back from the hash - for example if the password is a dictionary word it could be recovered using a dictionary attack. If the password is short enough and uses a characters from a limited range a brute force or rainbow table attack could recover the password. When you store a hashed password you should use a salt and key strengthening (for example PBKDF2) to make these attacks more difficult.
You should also be aware that MD5 is considered broken and it is recommended not to use it for new applications. There are better alternatives, for example SHA-256.
1) There is no decrypt for MD5.
2) MD5 is old technology which is excellent for checking to see if two strings are the same.
3) MD5 is subject to dictionary assaults.
4) MD5 can be made more secure by using a salt.
5) We use MD5 for low level security because the hash can be easily duplicated across platforms. (C++, vb.net, VB6, C#, php ...)
If you're going to use a hashing algorithm, you don't (can't) decrypt the password. You hash the password and store the hash. When the user provides their password in the future, you hash it with the same algorithm and compare the new hash with what you stored before.
You can use the MessageDigest class in Java to hash a value. Ref: Get MD5 hash in a few lines of Java.
Edit: Also, I agree with the others who are saying not to use MD5 for this anymore. It's an old algorithm that used to be common, but it's been attacked to the point of worthlessness (for passwords). There are all sorts of resources online for MD5 reverse lookup.
You can do it in postgres if you install the pgcrypto contrib module.
You can then encrypt passwords like this:
update ... set passwordhash = crypt('new password', gen_salt('md5'));
Of course you can't decrypt it at all!
As others have pointed out, this may be a bad idea, depending on what you are trying to do. I've been forced to use MD5 before because another application has demanded it, but you don't want to be broadcasting that hash to the world.
I've found the Jasypt encryption library to be quite useful.