MD5 hashing in Android

I have a simple Android client that needs to "talk" with a simple C # HTTP listener. I want to provide a basic level of authentication by passing username / password in POST requests.

MD5 hashing is trivial in C # and provides sufficient security for my needs, but I cannot find how to do this on the Android side.

EDIT: just to solve the problems associated with the weakness of MD5, the C # server runs on the users PC of my Android client. In many cases, they will access the server via Wi-Fi in their local networks, but at their own risk they can access it from the Internet. Also, the service on the server should use an end-to-end pass for MD5 for a third-party application in which I do not control.

+82
android cryptography md5
Jan 31 2018-11-11T00:
source share
13 answers

Here is an implementation you can use (updated to use more modern Java conventions - for:each loop, StringBuilder instead of StringBuffer ):

 public static final String md5(final String s) { final String MD5 = "MD5"; try { // Create MD5 Hash MessageDigest digest = java.security.MessageDigest .getInstance(MD5); digest.update(s.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuilder hexString = new StringBuilder(); for (byte aMessageDigest : messageDigest) { String h = Integer.toHexString(0xFF & aMessageDigest); while (h.length() < 2) h = "0" + h; hexString.append(h); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } 

Although this is not recommended for systems that provide even a basic level of security (MD5 is considered broken and can be easily used ), sometimes this is enough to perform basic tasks.

+208
Jan 31 2018-11-11T00:
source share

The accepted answer did not work for me in Android 2.2. I don't know why, but it "ate" some of my zeros (0). Apache commons also did not work on Android 2.2, because it uses methods that are only supported starting with Android 2.3.x. Also, if you want just an MD5 line, Apache Commons is too complicated for that. Why do I need to store the whole library in order to use only a small function from it ...

Finally, I found the following code snippet here that worked perfectly for me. I hope this is useful to someone ...

 public String MD5(String md5) { try { java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); byte[] array = md.digest(md5.getBytes("UTF-8")); StringBuffer sb = new StringBuffer(); for (int i = 0; i < array.length; ++i) { sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3)); } return sb.toString(); } catch (java.security.NoSuchAlgorithmException e) { } catch(UnsupportedEncodingException ex){ } return null; } 
+42
Jan 24 '14 at 13:17
source share

The androidsnippets.com code does not work reliably because 0 seems to be cut from the resulting hash.

The best implementation is here .

 public static String MD5_Hash(String s) { MessageDigest m = null; try { m = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } m.update(s.getBytes(),0,s.length()); String hash = new BigInteger(1, m.digest()).toString(16); return hash; } 
+25
May 30 '12 at 20:55
source share

If using Apache Commons Codec is an option, then this will be a shorter implementation:

 String md5Hex = new String(Hex.encodeHex(DigestUtils.md5(data))); 

Or SHA:

 String shaHex= new String(Hex.encodeHex(DigestUtils.sha("textToHash"))); 

Source above.

Please follow the link and confirm his decision to reward the person.




Maven repo link: https://mvnrepository.com/artifact/commons-codec/commons-codec

Current Maven dependency (as of July 6, 2016):

 <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> 
+17
May 20 '13 at 16:13
source share

The solution using DigestUtils did not help me. In my version of Apache commons (the last for 2013) there is no such class.

I found another solution here on one blog . It works great and does not need Apache shares. It looks a little shorter than the code in the accepted answer above.

 public static String getMd5Hash(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] messageDigest = md.digest(input.getBytes()); BigInteger number = new BigInteger(1, messageDigest); String md5 = number.toString(16); while (md5.length() < 32) md5 = "0" + md5; return md5; } catch (NoSuchAlgorithmException e) { Log.e("MD5", e.getLocalizedMessage()); return null; } } 

You will need to import:

 import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; 
+11
Dec 05 '13 at 10:57
source share

This is a small variation of Andranik and Den Delimarsky's answers above, but its a bit more concise and does not require any bitwise logic. Instead, it uses the built-in String.format method to convert bytes to two characters in hexadecimal strings (does not separate 0). Usually I just comment on their answers, but I don't have a reputation to do this.

 public static String md5(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); StringBuilder hexString = new StringBuilder(); for (byte digestByte : md.digest(input.getBytes())) hexString.append(String.format("%02X", digestByte)); return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } 

If you want to return a string string instead, just change %02X to %02X .

Edit: Using BigInteger as with wzbozon's answer, you can make the answer even more concise:

 public static String md5(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); BigInteger md5Data = new BigInteger(1, md.digest(input.getBytes())); return String.Format("%032X", md5Data); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } 
+8
Sep 09 '16 at 22:30
source share

I made a simple library in Kotlin.

Add to Root build.gradle

 allprojects { repositories { ... maven { url 'https://jitpack.io' } } } 

in build.gradle application

 implementation 'com.github.1AboveAll:Hasher:-SNAPSHOT' 

using

In Kotlin

 val ob = Hasher() 

Then use the hash () method

 ob.hash("String_You_Want_To_Encode",Hasher.MD5) ob.hash("String_You_Want_To_Encode",Hasher.SHA_1) 

He will return MD5 and SHA-1, respectively.

Library Details

https://github.com/1AboveAll/Hasher

+3
Apr 28 '18 at 8:37
source share

In our MVC application we generate for long param

 using System.Security.Cryptography; using System.Text; ... public static string getMD5(long id) { // convert string result = (id ^ long.MaxValue).ToString("X") + "-ANY-TEXT"; using (MD5 md5Hash = MD5.Create()) { // Convert the input string to a byte array and compute the hash. byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(result)); // Create a new Stringbuilder to collect the bytes and create a string. StringBuilder sBuilder = new StringBuilder(); for (int i = 0; i < data.Length; i++) sBuilder.Append(data[i].ToString("x2")); // Return the hexadecimal string. result = sBuilder.ToString().ToUpper(); } return result; } 

and same thing in android application (thenk helps Andranik)

 import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; ... public String getIdHash(long id){ String hash = null; long intId = id ^ Long.MAX_VALUE; String md5 = String.format("%X-ANY-TEXT", intId); try { MessageDigest md = java.security.MessageDigest.getInstance("MD5"); byte[] arr = md.digest(md5.getBytes()); StringBuffer sb = new StringBuffer(); for (int i = 0; i < arr.length; ++i) sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1,3)); hash = sb.toString(); } catch (NoSuchAlgorithmException e) { Log.e("MD5", e.getMessage()); } return hash.toUpperCase(); } 
+1
Nov 19 '14 at 8:32
source share

MD5 is a bit old, SHA-1 is the best algorithm, there is an example .

(Also, as they note in this post, Java handles this on its own, it does not have special Android code.)

0
Aug 15 2018-12-12T00:
source share

I used the method below to give me md5 by passing the string for which you want to get md5

 public static String getMd5Key(String password) { // String password = "12131123984335"; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(password.getBytes()); byte byteData[] = md.digest(); //convert the byte to hex format method 1 StringBuffer sb = new StringBuffer(); for (int i = 0; i < byteData.length; i++) { sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)); } System.out.println("Digest(in hex format):: " + sb.toString()); //convert the byte to hex format method 2 StringBuffer hexString = new StringBuffer(); for (int i = 0; i < byteData.length; i++) { String hex = Integer.toHexString(0xff & byteData[i]); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } System.out.println("Digest(in hex format):: " + hexString.toString()); return hexString.toString(); } catch (Exception e) { // TODO: handle exception } return ""; } 
0
Mar 17 '16 at 7:24
source share

In fact, too much wasteful toHex () conversion prevails in other sentences.

 private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); public static String md5string(String s) { return toHex(md5plain(s)); } public static byte[] md5plain(String s) { final String MD5 = "MD5"; try { // Create MD5 Hash MessageDigest digest = java.security.MessageDigest.getInstance(MD5); digest.update(s.getBytes()); return digest.digest(); } catch (NoSuchAlgorithmException e) { // never happens e.printStackTrace(); return null; } } public static String toHex(byte[] buf) { char[] hexChars = new char[buf.length * 2]; int v; for (int i = 0; i < buf.length; i++) { v = buf[i] & 0xFF; hexChars[i * 2] = HEX_ARRAY[v >>> 4]; hexChars[i * 2 + 1] = HEX_ARRAY[v & 0x0F]; } return new String(hexChars); } 
0
Mar 25 '16 at 11:41
source share

Please use SHA-512, MD5 is unsafe

 public static String getSHA512SecurePassword(String passwordToHash) { String generatedPassword = null; try { MessageDigest md = MessageDigest.getInstance("SHA-512"); md.update("everybreathyoutake".getBytes()); byte[] bytes = md.digest(passwordToHash.getBytes()); StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); } generatedPassword = sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return generatedPassword; } 
0
Apr 16 '19 at 3:21
source share

The presented solutions for the Scala language (a little shorter):

 def getMd5(content: Array[Byte]) = try { val md = MessageDigest.getInstance("MD5") val bytes = md.digest(content) bytes.map(b => Integer.toHexString((b + 0x100) % 0x100)).mkString } catch { case ex: Throwable => null } 
-one
Jul 11 '14 at 11:33
source share



All Articles