char[] -> String -> bytes[] -> String... and I'm lost - java

What I'm trying to do is to convert a password typed into a jPasswordField into SHA-256 hash. I was wandering around and found how to do this if I've got password saved as a string but the field I'm using is returning char[] so I ended up just guessing what to do... at first I've got different results even if the password was the same but now I believe I'm closer as it's a constant; but it's still not it as the output of
echo -n 'abc' | sha256sum
is
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
while the output of my action (for the same input) is
86900f25bd2ee285bc6c22800cfb8f2c3411e45c9f53b3ba5a8017af9d6b6b05
My action looks like this:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
NoSuchAlgorithmException noSuchAlgorithmException = null;
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException ex) {
noSuchAlgorithmException = ex;
}
if (noSuchAlgorithmException != null) {
System.out.println(noSuchAlgorithmException.toString());
}
else {
UnsupportedEncodingException unsupportedEncodingException = null;
byte[] hash = null;
char[] password = jPasswordField1.getPassword();
StringBuffer stringBuffer = new StringBuffer();
for (char c : password) {
if (c > 0 && c < 16) {
stringBuffer.append("0");
}
stringBuffer.append(Integer.toHexString(c & 0xff));
}
String passwordString = stringBuffer.toString();
try {
hash = messageDigest.digest(passwordString.getBytes("UTF-8"));
} catch (UnsupportedEncodingException ex) {
unsupportedEncodingException = ex;
}
if (unsupportedEncodingException != null) {
System.out.println(unsupportedEncodingException.toString());
}
else {
stringBuffer = new StringBuffer();
for (byte b : hash) {
stringBuffer.append(String.format("%02x", b));
}
String passwordHashed = stringBuffer.toString();
System.out.println(passwordHashed);
}
}
Any ideas?

You've pretty much nailed it. just took the hard/wrong way converting from char[] to String -> new String(password) is all you need. (hint, if you find yourself manually converting between bytes and chars, you're probably doing it wrong).
as a side note, exceptions are "thrown" for a reason. that makes it easy to skip the following code which shouldn't be executed when the exception is thrown. by catching and turning the exceptions into "if" blocks, you make the code more complex than it needs to be.

This prints out the same hash as sha256sum
public static void main(String[] args)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
char[] password = new char[]{'a', 'b', 'c'};
MessageDigest messageDigest = null;
messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hash = null;
// This is how you convert a char array into a String without reencoding it into a different set of characters.
String passwordString = new String(password);
hash = messageDigest.digest(passwordString.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
String passwordHashed = sb.toString();
System.out.println(passwordHashed);
}

Related

how can i find php md5(sha1("test")) in java

In my existing system, i have hashed the password with the following algorithm in php.
$userId = "testusername";
$password = "testpassword";
echo md5(sha1($userId).sha1($password));
what will be the equivalent method in Java for the above, because i was migrating php to java.
when i tried to search in google, they are talking about MessageDigest method.
In PHP i have used the inbuild md5() and sha1() function
in java, i found the following, but still, its not equivalent.
public static String sha1(String input) {
StringBuilder sb = null;
try{
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.reset();
md.update(input.getBytes());
byte[] bytes = md.digest();
sb = new StringBuilder();
for(int i=0; i< bytes.length ;i++)
{
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
}catch(RuntimeException | NoSuchAlgorithmException e){
throw new RuntimeException(e.getMessage());
}
return sb.toString();
}
public static String md5(String input) {
StringBuilder sb = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(input.getBytes());
byte[] bytes = md.digest();
sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
} catch (RuntimeException | NoSuchAlgorithmException e) {
throw new RuntimeException(e.getMessage());
}
return sb.toString();
}
}
You can try bellow example :
class Main {
public static void main(String[] a) throws UnsupportedEncodingException, NoSuchAlgorithmException {
String output, input = "ml";
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digest = md.digest(input.getBytes("UTF-8"));
BigInteger bigInt = new BigInteger(1, digest);
output = bigInt.toString(16);
System.out.println(""+output);
}
}
In the same way you also can generate sha1 just pass "sha1" in MessageDigest.getInstance(); function.
sha1($userId)+sha1($password) completely wrong. To do string concatenation in PHP you need sha1($userId).sha1($password)
The result you're seeing in PHP is actually md5(8) or c9f0f895fb98ab9159f51fd0297e236d. This is because the SHA1 of $password begins with an 8. The rest of the hash is thrown away.
This can not be used as a secure hashing function because there are too many collisions. For example, a password of 12345 has the same hash. You should require users to reset their passwords and use a standard password hashing mechanism instead.

what this android function returns

I am trying to decode an APK file. I need to get what m21862a function returns.
Simply I need HASH value. Hash is requested to https://api.SOMESITE.net/external/auth. How it is generated?
Here is my part code:
a = HttpTools.m22199a("https://api.somesite.net/external/hello", false);
String str = BuildConfig.FLAVOR;
str = BuildConfig.FLAVOR;
str = BuildConfig.FLAVOR;
try {
str = ((String) new JSONObject(a).get("token")) + ZaycevApp.f15130a.m21564W();
Logger.m22256a("ZAuth", "token - " + str);
str = m21862a(str);
a = new JSONObject(HttpTools.m22199a(String.format("https://api.SOMESITE.net/external/auth?code=%s&hash=%s", new Object[]{a, str}), false)).getString("token");
if (!ae.m21746b((CharSequence) a)) {
ZaycevApp.f15130a.m21595f(a);
}
}
I need to know what is m21862a function. Is there PHP replacement for m21862a? Here is m21862a function:
private String m21862a(String str) {
try {
MessageDigest instance = MessageDigest.getInstance("MD5");
instance.update(str.getBytes());
byte[] digest = instance.digest();
StringBuffer stringBuffer = new StringBuffer();
for (byte b : digest) {
String toHexString = Integer.toHexString(b & RadialCountdown.PROGRESS_ALPHA);
while (toHexString.length() < 2) {
toHexString = "0" + toHexString;
}
stringBuffer.append(toHexString);
}
return stringBuffer.toString();
} catch (Exception e) {
Logger.m22252a((Object) this, e);
return BuildConfig.FLAVOR;
}
}
The function computes the MD5 digest of the input, takes each byte of the computed MD5, "ANDize" with RadialCountdown.PROGRESS_ALPHA, translates to hex (pad with 0 to have 2 char) and appends that to the ouput.
There is probably a way to do the same thing in php (using md5()?).

convert byte array to string in java

I try to convert byte array to string in java using new String( bytes, "UTF-8") method, but they only return the object. like this #AB4634bSbbfa
So, I searched some way to solve this problem.
I finally get valid string array, by converting hex-code to basic-character array.
like this. char[] chars = {"0", "1", ... "e", "f"};
This never happened before why do i have to convert hex-code to get valid string.
Here is method.
byte array which is hashed by Mac-sha-256 with specific key when i hashed.
public static String getHashString() {
String algorithm = "HmacSHA256";
String hashKey = "some_key";
String message = "abcdefg";
String hexed = "";
try {
Mac sha256_HMAC = Mac.getInstance(algorithm);
SecretKeySpec secret_key = new SecretKeySpec(hashKey.getBytes(), algorithm);
sha256_HMAC.init(secret_key);
byte[] hash = sha256_HMAC.doFinal(message.getBytes("UTF-8"));
// it doesn't work for me.
// hexed = new String(hash, "UTF-8");
// it works.
hexed = bytesToHex(hash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return hexed;
}
public static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
public static String bytesToHex(final byte[] data ) {
final int l = data.length;
final char[] hexChars = new char[l<<1];
for( int i=0, j =0; i < l; i++ ) {
hexChars[j++] = HEX_DIGITS[(0xF0 & data[i]) >>> 4];
hexChars[j++] = HEX_DIGITS[0x0F & data[i]];
}
return new String(hexChars);
}
Thanks.
Following is a sample which shows Conversion of Byte array to String :-
public class TestByte
{
public static void main(String[] argv) {
String example = "This is an example";
byte[] bytes = example.getBytes();
System.out.println("Text : " + example);
System.out.println("Text [Byte Format] : " + bytes);
System.out.println("Text [Byte Format] : " + bytes.toString());
String s = new String(bytes);
System.out.println("Text Decryted : " + s);
}}
I'm not sure the string you get in the end is what you're after. I think a common scenario is to use
new BASE64Encoder().encode(hash)
which will return you the hashed message as String.
just do new String(byteArray);

Java SHA512 digest output differs from PHP script

Can someone figure out why the output of these (php and java) snippets of code don't return the same SHA512 for the same input?
$password = 'whateverpassword';
$salt = 'ieerskzcjy20ec8wkgsk4cc8kuwgs8g';
$salted = $password.'{'.$salt.'}';
$digest = hash('sha512', $salted, true);
echo "digest: ".base64_encode($digest);
for ($i = 1; $i < 5000; $i++) {
$digest = hash('sha512', $digest.$salted, true);
}
$encoded_pass = base64_encode($digest);
echo $encoded_pass;
This is the code on the android application:
public String processSHA512(String pw, String salt, int rounds)
{
try {
md = MessageDigest.getInstance("SHA-512");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("No Such Algorithm");
}
String result = hashPw(pw, salt, rounds);
System.out.println(result);
return result;
}
private static String hashPw(String pw, String salt, int rounds) {
byte[] bSalt;
byte[] bPw;
String appendedSalt = new StringBuilder().append('{').append(salt).append('}').toString();
try {
bSalt = appendedSalt.getBytes("ISO-8859-1");
bPw = pw.getBytes("ISO-8859-1");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported Encoding", e);
}
byte[] digest = run(bPw, bSalt);
Log.d(LCAT, "first hash: " + Base64.encodeBytes(digest));
for (int i = 1; i < rounds; i++) {
digest = run(digest, bSalt);
}
return Base64.encodeBytes(digest);
}
private static byte[] run(byte[] input, byte[] salt) {
md.update(input);
return md.digest(salt);
}
The library for base64 encoding is this: base64lib
This java code is actually some modified code I found around another question in StackOverflow.
Although the Android code is running fine it doesn't match with the output from the php script. It doesn't even match the first hash!
Note 1: On php hash('sha512',$input, $raw_output) returns raw binary output
Note 2: On java I tried to change the charset (UTF-8, ASCII) but it also didn't work.
Note 3: The code from the server can not be changed, so I would appreciate any answer regarding how to change my android code.
The first hash should be the same on the server and in Java. But then in the loop what gets appended to the digest is password{salt} in the PHP code, but only {salt} in the Java code.
For the lazy ones, one example better than a thousand words ;). I finally understood what was happening. The method update appends bytes to the digest, so when you append $password.{$salt} is the same as doing mda.update(password bytes) and the mda.digest("{$salt}" bytes. I do that answer because I was going crazy finding why it was not working and it was all in this answer.
Thanks guys.
This is the example that works in a Java Server:
public static String hashPassword(String password, String salt) throws Exception {
String result = password;
String appendedSalt = new StringBuilder().append('{').append(salt).append('}').toString();
String appendedSalt2 = new StringBuilder().append(password).append('{').append(salt).append('}').toString();
if(password != null) {
//Security.addProvider(new BouncyCastleProvider());
MessageDigest mda = MessageDigest.getInstance("SHA-512");
byte[] pwdBytes = password.getBytes("UTF-8");
byte[] saltBytes = appendedSalt.getBytes("UTF-8");
byte[] saltBytes2 = appendedSalt2.getBytes("UTF-8");
byte[] digesta = encode(mda, pwdBytes, saltBytes);
//result = new String(digesta);
System.out.println("first hash: " + new String(Base64.encode(digesta),"UTF-8"));
for (int i = 1; i < ROUNDS; i++) {
digesta = encode(mda, digesta, saltBytes2);
}
System.out.println("last hash: " + new String(Base64.encode(digesta),"UTF-8"));
result = new String(Base64.encode(digesta));
}
return result;
}
private static byte[] encode(MessageDigest mda, byte[] pwdBytes,
byte[] saltBytes) {
mda.update(pwdBytes);
byte [] digesta = mda.digest(saltBytes);
return digesta;
}

Java to VB.Net Conversion of This Function

I have a Java snippet here, I was wondering if it is possible to translate to VB.Net, as I have no found a snippet for VB.Net - only this:
private static byte[] SHA1(final String in)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(in.getBytes("iso-8859-1"), 0, in.length());
return md.digest();
}
public static String decryptSHA1(String key, final String start) {
final String delim = "a";
if (start == null)
return null;
byte[] hashedkey;
byte[] password;
int i;
try {
hashedkey = SHA1(key);
} catch (final NoSuchAlgorithmException e) {
e.printStackTrace();
return start;
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
return start;
}
final String[] temp = start.split(delim);
password = new byte[temp.length];
for (i = 0; i < hashedkey.length; i++) {
final int temp2 = Integer.parseInt(temp[i]);
if (hashedkey[i] == temp2) {
break;
} else {
password[i] = (byte) (temp2 - hashedkey[i]);
}
}
return new String(password, 0, i);
}
Thanks for any advice.
The hardest part here seems to be redoing the SHA1 method. You just need to find the equivalent .NET library classes/methods. Judging from the names, you probably want the System.Text.Encoding class and the System.Security.Cryptography.SHA1 class. Off hand, the algorithm probably ends up something like this
Private Shared Function SHA1(input As String) As Byte()
Dim iso8859 = System.Text.Encoding.GetEncoding("iso-8859-1")
Dim inBytes = ios8859.GetBytes(input)
' This is one implementation of the abstract class SHA1.'
Dim sha As New SHA1CryptoServiceProvider()
Return sha.ComputeHash(data)
End Function
From there you should be able to convert the rest of the decryptSHA1 function yourself as it is just basic byte manipulation. I will note that the GetEncoding function says it throws ArgumentException if you pass an invalid code page name and there does not seem to be any equivalent exception for NoSuchAlgorithmException to worry about catching.

Categories