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.
Related
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'm connecting lamp using JDBC and I have the word LondonWeight as a password hashed using MD5 on a MySQL database. I then need to check an inputted password against the collection, i.e LondonWeight to check to see if they match. However the hashing in my Java code returns a different output for the word.
MySQL hash:
1274d1c52d7a5a9125bd64f1f9a26dce
Java hash:
132310771724320562704545645352563257040366
Here's my hash code:
private String hashPass(String pass) throws NoSuchAlgorithmException {
MessageDigest mdEnc = MessageDigest.getInstance("MD5");
mdEnc.update(pass.getBytes(), 0, pass.length());
String md5 = new BigInteger(1, mdEnc.digest()).toString(8); // Encrypted
return md5;
}
It definitely hashes the String entered in the text box as I have it printed to the terminal so I can check. Any idea why it gives a different output? I understand there a different ways to hash the bytes or something?
You're currently converting the hash into octal in Java, whereas the MySQL version is in hex.
That's the first problem, but also:
Your MySQL hash appears to be 33 characters, which is too much data for an MD5 hash in hex. There's something odd going on there.
I wouldn't use BigInteger to convert a byte array into hex anyway; that's not what it's there for. Use Apache Commons Codec or something designed for hex conversion. For example, that way you'll get appropriate leading zeroes which BigInteger may suppress
Your current code assumes a single byte per character
Your current code assumes that the default character encoding is appropriate; I would suggest always specifying an encoding in String.getBytes
Using MD5 for password hashing is weak; update to a more appropriate hash if you possibly can
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.
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.
I am trying to hash a password and save it in the database; I know hashing is a one way process. How can I check whether the user supplied password and the one stored in the database are same? I am using MD5 and I am getting different values for the same input when I perform hashing each time. Can anyone help?
String pass = "wor1ldcup";
String pass1 = "wor1ldcup";
DigestUtils du = new DigestUtils();
byte[] b = du.md5(pass);
byte[] b1 = du.md5(pass1);
The code you supplied is basically correct, with a couple of caveats:
The methods of DigestUtils are all static, and hence should be invoked as:
byte[] b = DigestUtils.md5(...);
and not as
DigestUtils du = new DigestUtils(); // wrong ... no need to instantiate
byte[] b = du.md5(...); // wrong ... never use an instance to
// call a static method.
You don't show how you compare the b and b1, but b == b1 won't work, and neither will b.equals(b2) ... both compare references. You need to call Arrays.equals(b, b1).
It is a bad idea to try to turn an MD5 hash into a String. Depending on the default character set, the conversion may turn out to be lossy; i.e. not reversible. If you want to store an MD5 hash in a database, it is better to encode as a String using (for example) base64 encoding, and save the encoded hash.
You really should use bcrypt instead of MD5 for password storage. Here is an article on why (there are many more).
The jBcrypt library works well.
Use:
import java.security.*;
byte[] password;
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(password, 0, password.length);
byte[] passwordHashed = messageDigest.digest();
Need to convert String to byte[] and byte[] to hex or Base64 String.
Here's a few things to check:
Are you comparing the hashes in the same case? i.e. are the alphabetic digits in the hashes in lowercase in both versions?
Is it possible that a leading 0 has been truncated from the front of one of the hashes?
Are you comparing two Strings using == ? Use .equals instead.
If all of those are ok, the hashing should return the same value each time for the exact same input.
At the most basic level, when using a hashing function for passwords you hash the password when initially storing it and then hash any attempts to match that original.
So, when you are trying to validate a password for an existing user your basic query would use the hashed version of the submitted password as a parameter.
SELECT * FROM Users where ID = 1234 and Password = #Password
binding #Password to du.md5(submittedPassword)