public static String encryptPassword( String password ) {
String encrypted = "";
try {
MessageDigest digest = MessageDigest.getInstance( "MD5" );
byte[] passwordBytes = password.getBytes( );
digest.reset( );
digest.update( passwordBytes );
byte[] message = digest.digest( );
StringBuffer hexString = new StringBuffer();
for ( int i=0; i < message.length; i++)
{
hexString.append( Integer.toHexString(
0xFF & message[ i ] ) );
}
encrypted = hexString.toString();
}
catch( Exception e ) { }
return encrypted;
}
I am using Java. I used this method for hashing the password and it correctly worked while storing into the database. Now I have difficulty with decryption. Are there any methods more effective than this one?
You can't decrypt it. MD5 is a hash - it's one way, unlike a two-way encryption algorithm.
You generally shouldn't be trying to decrypt passwords though - you store the hash (salted, ideally) and then compare the "known good" hash with the hash of the password given to you by the user later.
(I would avoid MD5 these days personally, but that's another story.)
MD5 is a hash function, i.e. a one-way function. It is not possible to "decrypt" an MD5 code.
While not useful for encryption applications, hash codes are typically used for the following applications:
password storage:When user initially registers, the password he provides is submited to the hash function and the resulting code is kept on file. When he/she tries to login, the credential he passes then are submited to the same hash function, and the code so produced is compared to the hash code kept on file. The interesting benefit of this approach is that even if someone has access to the list of hash codes corresponding to users' password, he/she is not able to know what the passwords are, because if the irreversibility of the hash function.
detecting changes in data recordsThe MD5 code provides a short code which can summarize the content of a whole record (with a relatively low probability but not impossibility that a different record content could have the same MD5 value); this code can then be use to detect if the record was modified without requiring access to the original record. This is used for fraud detection and also for quickly computing differential update sets for datasets which are updated on batch basis.
Providing keys for database indexingAgain because of the relatively short size of the MD5 compared to the original data, MD5 or other other hash codes provide a way of building relatively compact indexes for data which may be quite long.
If you must... [store passwords so they can be retrieved at a later time] and BTW, there are many use cases where doing so is necessary (for example to be supplied to 3rd party site to login on-behalf of your application's various users etc.)...
...you should use a encryption algorithm such as Blowfish, DES, AES and the like (I'm only mentioning symmetric key encryption here, for while public key encryption may be used as well, it doesn't appear this is what is needed here).
Be sure to read-up about encryption and cryptography at large, for it is relatively easy to implement encryption-decryption applications which are not very secure :-( Also remember that the algorithm is only one of the elements (typically the "easier" one) of the whole chain.
Related
public static void main(String[] args) {
String s = "text";
hash=DatatypeConverter.printHexBinary(MessageDigest.getInstance("MD5").digest(s.getBytes("UTF8")))
System.err.println(hash);
}
You can't. That's what hashing is about. This is not a API or library limitation but a mathematical one, which is there by design.
You need to understand that hashing and encryption/ decryption are two completely different things (which are often used together).
Hashing
A hash, or to be precise, a cryptographic hash, is the result of a mathematical one-way function which means it is meant to be irreversible. Once something is hashed, it is not possible to get the text that was hashed back from it. This is at least true for good hash algorithms, which are not considered broken. MD5 as well as SHA1 are considered broken, so if you need this in a security context, use SHA-256 or even SHA-512 instead. If you just need this for a checksum, MD5 should be fine.
You can just use an MD5 hash value and type it into Google and get the result back. That is not what you want from a hash function. E.g. take your the hash 1cb251ec0d568de6a929b520c4aed8d1 which is the MD5 hash of your message text and you'll get a website which shows you the original text.
Another property of a hash it that for two different inputs it should ideally never have the same output. That is of course impossible as the set of possible messages to hash is much much bigger then the set of possible hash messages as hashes have a fixed length. But it should not be possible to generate such a hash collision artificially following some algorithm or clever input.
The only way to find out what was hashed is to hash many messages (brute-force) and see if the computed hash matches the hash to be cracked. See Rainbow tables for more information on this.
Hashes are mostly used to ensure integrity i.e. no modification was done to a message sent over the network. It is often used in conjunction with encryption algorithms (that's probably where your confusion originates from) as you need more than integrity to guarantee secure communication i.e. additionally authentication (e.g. by using certificates) and confidentiality (this is provided by encryption algorithms).
Encryption
An encryption function is a function which takes a message and a key and produces a result which is not readable unless you have the key. Side note: there may be one or two keys for encryption/ decryption depending on the algorithm you use (symmetric vs. asymmetric). If you have the key, it is reversible by applying the decryption function. If it was a one-way function like a hash, encryption would make no sense, as a recipient of a message would not be able to retrieve the message.
This question already has answers here:
How to reverse MD5 to get the original string? [duplicate]
(2 answers)
Closed 2 years ago.
I am looking into md5 hashing in java with the MessageDigest Class, lets say I do that
public void givenPassword_whenHashingUsingCommons_thenVerifying() {
String hash = "35454B055CC325EA1AF2126E27707052";
String password = "ILoveJava";
String md5Hex = DigestUtils
.md5Hex(password).toUpperCase();
assertThat(md5Hex.equals(hash)).isTrue();
}
So i did convert my password String into an md5 hash, lets say my recipient now wants the String not as hash, but as an normal String ( The Hash is just for transmission ), how can i convert the md5 hash String back to an "normal" Text String?
There is no way to convert a hash (MD5 or SHA1 or SHA2....) into the original string.
The purpose of a hashing function is a one-way translation. There is no coming back.
The MD5 hash function is an outdated cryptographic function that generates fixed length hashes of an input data. The how and whys is beyond the scope of this answer. I urge you to visit detailed texts on these online.
Please also remember that if you are using the MD5 for cryptographic and sensitive reasons, please learn about more secure recommended hashing as SHA256 etc..
For more details, please refer to this introductory text.
The reason that we hash passwords in particular is because it's one way and this is good for security reasons. Imagine a bad actor got access to your database, we wouldn't want them to be able to look up the password and log in as the user. By storing the hashed password, we can perform the same hashing algorithm on the password on login and compare it with the database value in the database for a successful login.
Even this has its issues. When bad actors gain access to a compromised database, they can generate "rainbow tables" to get from the hashed value to the password. Using common hashing algorithms and software such as hashcat they build up a database of common passwords, dictionary words etc. then match the hash value to the plain text string. This is why when storing passwords, we also use salting, which can be easily researched, Google "salting and hashing".
I see another answer which states that "The purpose of the hashing function is a one way translation". I think this is an over simplification. A hashing algorithm returns a message digest. It's a fixed length alphanumeric message which, as uniquely as possibly, represents the input. One the most important properties of a hashing algorithm is the uniqueness of the message and that it differs significantly from that of similar inputs. Here's an example using MD5:
String: aaaaaaaaaa
Hash: e09c80c42fda55f9d992e59ca6b3307d
String: aaaaaaaaab
Hash: ba05a43d3b98a72379fdc90a1e28ecaf
I am converting my password in Md5 , its working fine and giving me md5 converted password but i also want to have special characters in my md5 password.
how can i achieve this
public String createMd5(String password){
String salt = "Random$SaltValue#WithSpecialCharacters12#$#4&#%^$*";
String hash = md5(password + salt);
return hash;
}
public static String md5(String input) {
String md5 = null;
if(null == input) return null;
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(input.getBytes(), 0, input.length());
md5 = new BigInteger(1, digest.digest()).toString(32);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}
md5() is a hash function that maps from any string to {0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}^32.
You usually use it when you want to make sure that in case of a successful attack (this means the attacker could get your users data) the attacker does not have all users plaintext passwords (and hack e.g. their email accounds with this information).
You cannot get special characters out of md5() and it would not improve anything.
WARNING: MD5 should not be used anymore for hashing passwords as it is too fast to calculate (more information). Instead, you should use bcrypt with salt (example).
there is nothing like "md5 converted password" md5 generates checksum which you can not control.
I think this question stems from a misunderstanding of password hashing. Hashed passwords work like this:
A hash function is deterministic, that is, with the same input you always get the same output.
A good hash function is one-way, that is, you can't get from the hash value to the input without a lot of effort.
So take a password + salt (the salt makes creating an exhaustive dictionary MUCH harder)
Feed that into the hash function to generate a hash.
Store the hash and the salt.
To check passwords hash the user input and the stored salt and compare to the stored hash.
This operates on the byte level, so special characters are obviously included in the input. The output of the hash function is represented in hexadecimal for your convenience and does not contain special characters. If you do want the raw output just parse the hexadecimal representation into bytes but I don't see why you would want to, it's still the same number of output bits represented differently.
Another thing to note: MD5 is not a good hash function for passwords because it is much too fast. A really fast hash function is a hash function where trying a large amount of passwords from a generator is a trivial task. You might want to look for something more password specific for this use case.
I'm creating a simple web application and want to store hashed passwords into a database. I need the hash function for the authentication token too (concatenating the user name and the date and send them with their hash to the client as the token).
I've found that MessageDigest Java class can help me with this. Here is one link.
The basic idea goes like this:
public String digestString (String stringToHash) throws NoSuchAlgorithmException {
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] stringBytes = stringToHash.getBytes();
byte[] stringDigest = sha256.digest(stringBytes);
return new String(stringDigest);
}
What I don't get is:
In this code, how can I set the hash key? I need to be sure that the same key will be used in the verification process. How can I do that if I don't set the key?
BTW: I know I should add a salt (256 bytes in this case) to the hashed text before hashing it.
A hash uses no key. It's just a one-way algorithm. You give it something to digest, and it returns a hash. What it guarantees is that it's extremely hard to find the original input or any other input that leads to the same hash.
Your algorithm has two basic problems (besides the lack of salting):
it uses String.getBytes(), which relied on the default platform encoding, and thus differs from platform to platform. You should specify an encoding such as UTF-8.
it uses new String(byte[]), which has the same problem as above + an additional one: all the sequence of bytes are not valid character. To transform a purely binary byte array into a String, use a base64 encoding algorithm. apache commons codes has one.
Alright, so im trying to learn a little about Encrypting messages in my java application. I just found out that SALT and KEY aren't the same.
Can someone help me understand what the difference between the two is?
The key is, crudely, the equivalent of a password; you use it to encrypt a message, and then the same key gets used to decrypt it back to the original plaintext. (Well, it gets a little more complex, once you have public and private keys, and so on.)
A salt is most typically encountered with cryptographic hash functions, not encryption functions. The idea is that rather than hashing just your data (e.g. a password), you hash data+salt, where salt is typically a randomly-generated string. They have (at least) two purposes:
To foil an attacker who has access to the hashed data from identifying a collision using a rainbow table.
To slow down an attacker who's trying a brute-force attack.
The key is essentially the password with which you lock the original content.
To make the password more difficult to reverse engineer, you can add a salt to the produced encryption.
To give an obviously simple example, lets say you want to encrypt a character string. Your encryption routine is to reverse the word.
So, for the string "Hello, World", after running encryption, your string would be "dlroW ,olleH".
You could then add a salt to it. In this example, the salt will be "foo", so the result after salting would be "dlroW ,olleHfoo".
Now, if someone managed to reverse engineer your encryption algorithm, they'd get "oofHello World", which is not the original message, and thus your information is still safe!
This really comes into use when you iteratively encrypt, eg,
result = salt + encrypt(salt+encrypt(salt+encrypt(message))).