Saya memiliki klien android sederhana yang perlu 'berbicara' dengan pendengar HTTP C # sederhana. Saya ingin memberikan tingkat dasar otentikasi dengan meneruskan nama pengguna / kata sandi dalam permintaan POST.
Hash MD5 sepele di C # dan memberikan keamanan yang cukup untuk kebutuhan saya, tetapi saya tidak dapat menemukan cara melakukan ini di ujung android.
EDIT: Hanya untuk mengatasi kekhawatiran yang muncul tentang kelemahan MD5 - server C # berjalan di PC pengguna klien android saya. Dalam banyak kasus, mereka akan mengakses server menggunakan wi-fi di LAN mereka sendiri tetapi, dengan risiko mereka sendiri, mereka dapat memilih untuk mengaksesnya dari internet. Juga layanan di server perlu menggunakan pass-through untuk MD5 ke aplikasi pihak ke-3 yang tidak dapat saya kendalikan.
sumber
Jawaban:
Berikut adalah implementasi yang dapat Anda gunakan (diperbarui untuk menggunakan lebih banyak konvensi Java terbaru -
for:each
loop,StringBuilder
daripadaStringBuffer
):public static 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 ""; }
Meskipun tidak disarankan untuk sistem yang melibatkan bahkan tingkat keamanan dasar (MD5 dianggap rusak dan dapat dengan mudah dieksploitasi ), terkadang cukup untuk tugas-tugas dasar.
sumber
NoSuchAlgorithmException
)?Jawaban yang diterima tidak berhasil untuk saya di Android 2.2. Saya tidak tahu mengapa, tapi itu "memakan" sebagian dari nol saya (0). Apache commons juga tidak berfungsi di Android 2.2, karena menggunakan metode yang hanya didukung mulai dari Android 2.3.x. Juga, jika Anda hanya ingin MD5 sebuah string, Apache commons terlalu rumit untuk itu. Mengapa seseorang harus menyimpan seluruh perpustakaan untuk menggunakan hanya fungsi kecil darinya ...
Akhirnya saya menemukan potongan kode berikut di sini yang bekerja dengan sempurna untuk saya. Semoga bermanfaat bagi seseorang ...
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; }
sumber
Kode androidsnippets.com tidak berfungsi dengan andal karena 0 tampaknya dipotong dari hash yang dihasilkan.
Implementasi yang lebih baik ada di sini .
sumber
Jika menggunakan Apache Commons Codec adalah sebuah opsi, maka ini adalah implementasi yang lebih singkat:
String md5Hex = new String(Hex.encodeHex(DigestUtils.md5(data)));
Atau SHA:
String shaHex= new String(Hex.encodeHex(DigestUtils.sha("textToHash")));
Sumber di atas.
Silakan ikuti tautan dan beri suara positif solusinya untuk memberi penghargaan kepada orang yang tepat.
Tautan repo Maven: https://mvnrepository.com/artifact/commons-codec/commons-codec
Ketergantungan Maven saat ini (per 6 Juli 2016):
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency>
sumber
Solusi di atas menggunakan DigestUtils tidak berhasil untuk saya. Dalam versi Apache commons saya (yang terbaru untuk 2013) tidak ada kelas seperti itu.
Saya menemukan solusi lain di sini di satu blog . Ia bekerja dengan sempurna dan tidak membutuhkan Apache commons. Ini terlihat sedikit lebih pendek dari kode dalam jawaban yang diterima di atas.
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; } }
Anda akan membutuhkan impor ini:
import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
sumber
Ini adalah variasi kecil dari jawaban Andranik dan Den Delimarsky di atas, tetapi sedikit lebih ringkas dan tidak memerlukan logika bitwise. Sebaliknya ia menggunakan metode built-in
String.format
untuk mengubah byte menjadi dua karakter string heksadesimal (tidak menghapus 0). Biasanya saya hanya akan mengomentari jawaban mereka, tetapi saya tidak memiliki reputasi untuk melakukannya.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; } }
Jika Anda ingin mengembalikan string huruf kecil, ubah saja
%02X
ke%02x
.Sunting: Menggunakan BigInteger seperti dengan jawaban wzbozon, Anda dapat membuat jawabannya lebih ringkas:
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; } }
sumber
Saya telah membuat Library sederhana di Kotlin.
Tambahkan di Root build.gradle
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
di App build.gradle
implementation 'com.github.1AboveAll:Hasher:-SNAPSHOT'
Pemakaian
Di Kotlin
val ob = Hasher()
Kemudian Gunakan metode hash ()
ob.hash("String_You_Want_To_Encode",Hasher.MD5) ob.hash("String_You_Want_To_Encode",Hasher.SHA_1)
Ini akan mengembalikan MD5 dan SHA-1 Masing-masing.
Lebih lanjut tentang Perpustakaan
https://github.com/ihimanshurawat/Hasher
sumber
Ini adalah versi Kotlin dari jawaban @Andranik. Kita perlu mengubah
getBytes
ketoByteArray
(tidak perlu menambahkan charset UTF-8 karena charset defaulttoByteArray
adalah UTF-8) dan cast array [i] menjadi integerfun String.md5(): String? { try { val md = MessageDigest.getInstance("MD5") val array = md.digest(this.toByteArray()) val sb = StringBuffer() for (i in array.indices) { sb.append(Integer.toHexString(array[i].toInt() and 0xFF or 0x100).substring(1, 3)) } return sb.toString() } catch (e: java.security.NoSuchAlgorithmException) { } catch (ex: UnsupportedEncodingException) { } return null }
Semoga membantu
sumber
Dalam aplikasi MVC kami, kami menghasilkan parameter panjang
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; }
dan sama di aplikasi Android (thenk membantu 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(); }
sumber
saya telah menggunakan metode di bawah ini untuk memberi saya md5 dengan melewatkan string yang ingin Anda dapatkan 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 ""; }
sumber
Harap gunakan SHA-512, MD5 tidak aman
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; }
sumber
MD5 agak tua, SHA-1 adalah algoritme yang lebih baik, ada contohnya di sini .
( Juga seperti yang mereka catat di posting itu, Java menangani ini sendiri, tidak ada kode khusus Android. )
sumber
Konversi toHex () yang terlalu boros berlaku di saran lain, sungguh.
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); }
sumber
ini bekerja dengan sempurna untuk saya, saya menggunakan ini untuk mendapatkan MD5 di LIST Array (kemudian mengubahnya menjadi objek JSON), tetapi jika Anda hanya perlu menerapkannya pada data Anda. ketik format, ganti JsonObject dengan milik Anda.
Terutama jika Anda memiliki ketidakcocokan dengan implementasi python MD5, gunakan ini!
private static String md5(List<AccelerationSensor> sensor) { Gson gson= new Gson(); byte[] JsonObject = new byte[0]; try { JsonObject = gson.toJson(sensor).getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } MessageDigest m = null; try { m = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } byte[] thedigest = m.digest(JsonObject); String hash = String.format("%032x", new BigInteger(1, thedigest)); return hash; }
sumber
Contoh Fungsi Ekstensi Kotlin yang Berguna
fun String.toMD5(): String { val bytes = MessageDigest.getInstance("MD5").digest(this.toByteArray()) return bytes.toHex() } fun ByteArray.toHex(): String { return joinToString("") { "%02x".format(it) } }
sumber
Solusi yang disediakan untuk bahasa Scala (sedikit lebih pendek):
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 }
sumber