I am using following code to encrypt my email id in Java and sending it as a parameter in url (Using URLEncoder.encode(encrypteInput("email"))):
public static String encrypteInput(String input) {
String output = null;
input = input + ((int) Math.random()) % 1000;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
output = new String(md5.digest(input.getBytes()));
} catch (Exception e) {
output = "";
}
return output;
}
but, when I am getting the same parameter from servlet, it is not giving me the same output as encrypteInput("email").
Whenever you have a byte array that you want to store in a string, you should be Hex- or Base64-encoding the byte array (hex-encoding is probably better in this particular case).
Apache commons-codec has a Hex class you can use for this:
byte[] bytes = ...
char[] encoded = Hex.encodeHex(bytes);
String encodedString = new String(encoded);
Related
I'm coding in Android Studio and I'm trying to create base64 encoded and sha512 hashed String.
The functions are:
private String getBase64(String data){
try{
byte[] enc = data.getBytes("UTF-8");
return Base64.encodeToString(enc, Base64.DEFAULT);
}catch (Exception e){
e.printStackTrace();
return null;
}
}
private String getSHA(String data){
try {
MessageDigest mda = MessageDigest.getInstance("SHA-512");
byte[] digesta = mda.digest(data.getBytes("UTF-8"));
return convertByteToHex(digesta);
}catch(Exception e){
e.printStackTrace();
return null;
}
}
public String convertByteToHex(byte data[]) {
StringBuilder hexData = new StringBuilder();
for (byte aData : data)
hexData.append(String.format("%02x", aData));
return hexData.toString();
}
Then calling them:
// line below prints VGVzdDox as it should
Log.d("GO", "Working Base64: " + getBase64("Test:1"));
// line below prints: 3553AF9EDC389314B0F7354B51FEA7EB089C039EA77A0FD7BD61798A8DD14B1292B353B9E00789B2698B072AF5B05417DDDAA1870ADF9E1DE9C1F96D9465DF56
// as it should
Log.d("GO", "Working SHA: " + getSHA("VGVzdDox"));
String b = getBase64("Test:1");
// line below prints VGVzdDox again, as it should
Log.d("Base64", b);
String s = getSHA(b);
// Now this line prints a7d1bdc5d6497d787b35ce52774365150a2e21084958ffc14570367f3764b938fc1191d06006f1908084518c9697cbff3f2830a1ac003ef8ace36a0667dce92d
// Not sure why?
Log.d("SHA", s);
So that last output is wrong. However the getBase64 is right and the getSHA also when hard coding the base64 encoded String. And I have no idea why.
This is just the main activity, no other code is executed.
it seems like your String
b
have a new line at the end, i tested it with an online sha 512 generator with the String:
"VGVzdDox" and
"VGVzdDox
"
output of the first one is:
3553AF9EDC389314B0F7354B51FEA7EB089C039EA77A0FD7BD61798A8DD14B1292B353B9E00789B2698B072AF5B05417DDDAA1870ADF9E1DE9C1F96D9465DF56
the out put for the second is:
A7D1BDC5D6497D787B35CE52774365150A2E21084958FFC14570367F3764B938FC1191D06006F1908084518C9697CBFF3F2830A1AC003EF8ACE36A0667DCE92D
so get rid of the line seperator maybe with the method Stirng.trim(), but i didn't tested it
Found it, had to change:
return Base64.encodeToString(enc, Base64.DEFAULT);
to
return Base64.encodeToString(enc, Base64.NO_WRAP);
For a class, I was given a file of base64 encoded salted sha-256 hashed passwords.
the file is in the form:
username:base64 encoded sha256 password:salt
My original thought was to base64 decode the hash so I would be left with:
username:salted hashed password:salt
then run it through JTR or hashcat to crack the passwords.
My problem is in the base64 decoding process.
my code looks like:
public static byte[] decode(String string) {
try {
return new BASE64Decoder().decodeBuffer(string);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void splitLine(String strLine)
throws Exception {
StringTokenizer st = new StringTokenizer(strLine, ":");
if (st.hasMoreTokens())
userName = st.nextToken();
if (st.hasMoreTokens())
password = st.nextToken();
if (st.hasMoreTokens())
salt = st.nextToken();
}
public static void main(String[] argv) {
String line = null;
String pwdFile = null;
int count = 0;
try {
pwdFile = argv[0];
BufferedReader br = new BufferedReader(new FileReader(pwdFile));
line = br.readLine();
while (line != null) {
splitLine(line);
/* alternative #1: generates a lot of non-printable characters for the hash */
System.out.println(userName+":"+new String(decode(password))+":"+salt);
/* alternative #2: gives a list of the decimal values for each byte of the hash */
System.out.println(userName+":"+Arrays.toString(decode(password))+":"+salt);
count++;
line = br.readLine();
}
br.close();
System.err.println("total lines read: " + count);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
With alternative #1, I end up with 50,000 more lines in my output file than were in the input file, so i assume some of the decoded strings contain newline characters which I need to fix as well.
How do I get back to and print the original hash value for the password in a format that either hashcat or JTR will recognize as salted sha256?
Problem: You are trying to to work with Base64 encoded password hashes and when they are decoded, there are unprintable characters
Background: When a value is hashed, the bytes are all changed according to a hashing algorithm and the resulting bytes are often beyond the range of printable characters. Base64 encoding is simply an alphabet that maps ALL bytes into printable characters.
Solution: work with the bytes that Base64 decode returns instead of trying to make them into a String. Convert those raw bytes to Hex representations (Base16) before you print them or give them to Hashcat or JTR. In short, you need to do something like the following (it happens to use Guava library):
String hex = BaseEncoding.base16().encode(bytesFromEncodedString);
This is condensed from a longer answer I posted
I have written following function to compute Md5 checksum in Java.
class Utils {
public static String md5Hash(String input) {
String result = "";
try {
System.out.println("Input=" + input);
final MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
md.update(input.getBytes());
result = md.digest().toString();
} catch (Exception ee) {
System.err.println("Error computing MD5 Hash");
}
return result;
}
};
Calling Utils.md5Hash("abcde") multiple times gives different results. My understanding says md5 returns a deterministic and unique checksum for a string. Is that wrong? Else please let me know the bug in my implementation. Thanks
The toString() method of a byte array doesn't return a meaningful string. It returns the type of the array object, followed by the hashCode of the array.
Transform the byte array to a String using Hex or Base64 encoding if you want it printed. Apache commons-codec has methods to do that.
Also, make sure to specify en encoding which supports any kind of character to transform your string to a byte array. The method you're using uses the platform default encoding, which could fail if, for example, it's latin-1 and you're transforming non-latin-1 characters. UTF-8 is a good choice.
I have done using the following way :
public static String encryptedLoginPassword( String password )
{
String encryptedData="";
try{
MessageDigest algorithm = MessageDigest.getInstance("MD5");
byte[] defaultBytes = password.getBytes();
algorithm.reset();
algorithm.update(defaultBytes);
byte messageDigest[] = algorithm.digest();
StringBuffer hexString = new StringBuffer();
for (int i=0;i<messageDigest.length;i++) {
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
}
encryptedData=hexString.toString();
}catch(NoSuchAlgorithmException nsae){
}
return encryptedData;
}
int the code given by Dinup Kandel, I had to change this:
for (int i=0;i<messageDigest.length;i++) {
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
}
in to
if ((0xff & messageDigest[i]) < 0x10) {
hexString.append("0"
+ Integer.toHexString((0xFF & messageDigest[i])));
} else {
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
}
to get my unit tests working.
note: i used this to verify the correct answer:
echo -n MyTestString | md5sum
Here is the code for my class:
public class Md5tester {
private String licenseMd5 = "?jZ2$??f???%?";
public Md5tester(){
System.out.println(isLicensed());
}
public static void main(String[] args){
new Md5tester();
}
public boolean isLicensed(){
File f = new File("C:\\Some\\Random\\Path\\toHash.txt");
if (!f.exists()) {
return false;
}
try {
BufferedReader read = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
//get line from txt
String line = read.readLine();
//output what line is
System.out.println("Line read: " + line);
//get utf-8 bytes from line
byte[] lineBytes = line.getBytes("UTF-8");
//declare messagedigest for hashing
MessageDigest md = MessageDigest.getInstance("MD5");
//hash the bytes of the line read
String hashed = new String(md.digest(lineBytes), "UTF-8");
System.out.println("Hashed as string: " + hashed);
System.out.println("LicenseMd5: " + licenseMd5);
System.out.println("Hashed as bytes: " + hashed.getBytes("UTF-8"));
System.out.println("LicenseMd5 as bytes: " + licenseMd5.getBytes("UTF-8"));
if (hashed.equalsIgnoreCase(licenseMd5)){
return true;
}
else{
return false;
}
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
return false;
} catch (NoSuchAlgorithmException e) {
return false;
}
}
}
Here's the output I get:
Line read: Testing
Hashed as string: ?jZ2$??f???%?
LicenseMd5: ?jZ2$??f???%?
Hashed as bytes: [B#5fd1acd3
LicenseMd5 as bytes: [B#3ea981ca
false
I'm hoping someone can clear this up for me, because I have no clue what the issue is.
A byte[] returned by MD5 conversion is an arbitrary byte[], therefore you cannot treat it as a valid representation of String in some encoding.
In particular, ?s in ?jZ2$??f???%? correspond to bytes that cannot be represented in your output encoding. It means that content of your licenseMd5 is already damaged, therefore you cannot compare your MD5 hash with it.
If you want to represent your byte[] as String for further comparison, you need to choose a proper representation for arbitrary byte[]s. For example, you can use Base64 or hex strings.
You can convert byte[] into hex string as follows:
public static String toHex(byte[] in) {
StringBuilder out = new StringBuilder(in.length * 2);
for (byte b: in) {
out.append(String.format("%02X", (byte) b));
}
return out.toString();
}
Also note that byte[] uses default implementation of toString(). Its result (such as [B#5fd1acd3) is not related to the content of byte[], therefore it's meaningless in your case.
The ? symbols in the printed representation of hashed aren't literal question marks, they're unprintable characters.
You get this error when your java file format is not UTF-8 encoding while you encode a string using UTF-8, try remove UTF-8 and the md5 will output another result, you can copy to the string and see the result true.
Another way is set the file encoding to UTF-8, the string encode also be different
My question is, I guess, quite simple :
How to convert a Byte to alpha-numeric char array (String) in java ?
I tried this but it gives me back an error on netbeans :
byte[] b = "test".getBytes("ASCII");
String test = new String(b,"ASCII");
UPDATE :
I am actually using this code :
byte[] b = "test".getBytes("ASCII");
MessageDigest md = MessageDigest.getInstance("SHA-256");
String bla = new String(md.digest(b), "ASCII");
But once I try to use for other stuff which requires String with ASCII, I receive the following errors like "This is not ASCII".
I don't really understand, actually.
When I try to print it I got something weird like "2Q�h/�k�����"
Thank you in advance for your help.
You're close :
public static void main(String[] args) throws java.io.UnsupportedEncodingException { //you should throw or catch this exception
byte[] b = "test".getBytes("ASCII"); // And you must declare a byte array
String test = new String(b,"ASCII");
System.out.println(test); // Will output "test"
}
After your edits I think you want to generate a SHA-256 hash of a given String.
try {
byte[] b = "test".getBytes("ASCII");
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = md.digest(b);
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hashBytes.length; i++) {
hexString.append(Integer.toHexString(0xFF & hashBytes[i]));
}
System.out.println(hexString);
} catch (Exception e) {
e.printStackTrace();
}