Android의 MD5 해싱
간단한 C # HTTP 리스너와 '대화'해야하는 간단한 안드로이드 클라이언트가 있습니다. POST 요청에서 사용자 이름 / 암호를 전달하여 기본 수준의 인증을 제공하고 싶습니다.
MD5 해싱은 C #에서 사소하고 내 요구에 충분한 보안을 제공하지만 Android 쪽에서이 작업을 수행하는 방법을 찾을 수없는 것 같습니다.
편집 : MD5 약점에 대해 제기 된 문제를 해결하기 위해 C # 서버는 내 안드로이드 클라이언트 사용자의 PC에서 실행됩니다. 대부분의 경우 그들은 자신의 LAN에서 Wi-Fi를 사용하여 서버에 액세스하지만 자신의 책임하에 인터넷에서 액세스하도록 선택할 수 있습니다. 또한 서버의 서비스는 내가 제어 할 수없는 타사 응용 프로그램에 대한 MD5 패스 스루를 사용해야합니다.
여기에 - 당신이 사용할 수있는 구현입니다 (날짜 Java 규약에 더 많은 최대 사용하도록 업데이트 for:each
, 루프를 StringBuilder
대신 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 "";
}
기본 보안 수준 (MD5 는 손상된 것으로 간주되고 쉽게 악용 될 수 있음 ) 조차 포함하는 시스템에는 권장되지 않지만 때로는 기본 작업에 충분합니다.
받아 들인 대답은 Android 2.2에서 작동하지 않았습니다. 이유는 모르겠지만 제 0 (0) 중 일부를 "먹고"있었습니다. Apache commons 는 Android 2.3.x부터 만 지원되는 메서드를 사용하기 때문에 Android 2.2에서도 작동하지 않았습니다. 또한 MD5 문자열을 원한다면 Apache commons는 너무 복잡합니다. 작은 기능 만 사용하기 위해 전체 라이브러리를 유지해야하는 이유 ...
마지막으로 여기 에서 완벽하게 작동 하는 다음 코드 스 니펫을 찾았 습니다. 누군가에게 도움이 되길 바랍니다 ...
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;
}
androidsnippets.com 코드는 결과 해시에서 0이 잘린 것처럼 보이기 때문에 안정적으로 작동하지 않습니다.
더 나은 구현이 여기에 있습니다 .
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; }
Apache Commons Codec을 사용하는 것이 옵션 인 경우 구현이 더 짧습니다.
String md5Hex = new String(Hex.encodeHex(DigestUtils.md5(data)));
또는 SHA :
String shaHex= new String(Hex.encodeHex(DigestUtils.sha("textToHash")));
위의 출처 .
링크를 따라 그의 솔루션을 찬성하여 올바른 사람을 선정하십시오.
Maven 저장소 링크 : https://mvnrepository.com/artifact/commons-codec/commons-codec
현재 Maven 종속성 (2016 년 7 월 6 일 기준) :
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
DigestUtils를 사용하는 위의 솔루션은 저에게 효과적이지 않았습니다. 내 버전의 Apache commons (2013 년 최신 버전)에는 그러한 클래스가 없습니다.
여기 한 블로그에서 또 다른 해결책을 찾았습니다 . 완벽하게 작동하며 Apache commons가 필요하지 않습니다. 위의 답변에 나온 코드보다 약간 짧아 보입니다.
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;
}
}
다음 가져 오기가 필요합니다.
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
이것은 위의 Andranik 및 Den Delimarsky 답변의 약간 변형이지만 조금 더 간결하고 비트 논리가 필요하지 않습니다. 대신 내장 String.format
메서드를 사용하여 바이트를 두 문자 16 진수 문자열로 변환합니다 (0을 제거하지 않음). 일반적으로 나는 그들의 대답에 대해 논평을했지만 그렇게 할 명성이 없습니다.
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;
}
}
대신 소문자 문자열을 반환 %02X
하려면 %02x
.
편집 : wzbozon의 답변과 같이 BigInteger를 사용하면 답변을 더욱 간결하게 만들 수 있습니다.
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;
}
}
Kotlin에서 간단한 라이브러리를 만들었습니다.
루트 build.gradle에 추가
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
App build.gradle에서
implementation 'com.github.1AboveAll:Hasher:-SNAPSHOT'
용법
Kotlin에서
val ob = Hasher()
그런 다음 hash () 메서드 사용
ob.hash("String_You_Want_To_Encode",Hasher.MD5)
ob.hash("String_You_Want_To_Encode",Hasher.SHA_1)
MD5 및 SHA-1을 각각 반환합니다.
도서관에 대한 추가 정보
https://github.com/1AboveAll/Hasher
MVC 애플리케이션에서 우리는 긴 매개 변수를 생성합니다.
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;
}
Android 애플리케이션에서도 동일합니다 (thenk는 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();
}
나는 아래 방법을 사용하여 md5를 얻고 싶은 문자열을 전달하여 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 "";
}
MD5는 약간 오래되었고 SHA-1은 더 나은 알고리즘이며 여기에 예제가 있습니다 .
( 또한 해당 게시물에서 언급했듯이 Java는 Android 특정 코드가 아닌 자체적으로이를 처리합니다. )
너무 낭비적인 toHex () 변환은 실제로 다른 제안에서 우세합니다.
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);
}
SHA-512를 사용하세요. MD5는 안전하지 않습니다.
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;
}
Here is Kotlin version from @Andranik answer. We need to change getBytes
to toByteArray
(don't need to add charset UTF-8 because the default charset of toByteArray
is UTF-8) and cast array[i] to integer
fun 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
}
Hope it help
this is working perfectly for me, I used this to get MD5 on LIST Array(then convert it to JSON object), but if you only need to apply it on your data. type format, replace JsonObject with yours.
Especially if you have a mismatch with python MD5 implementation use this!
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;
}
The provided 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
}
참고URL : https://stackoverflow.com/questions/4846484/md5-hashing-in-android
'IT story' 카테고리의 다른 글
Android Studio에 텍스트를 대문자로 변환하는 바로 가기가 있습니까? (0) | 2020.09.12 |
---|---|
입력 유형 = 파일을 이미지로 바꾸기 (0) | 2020.09.12 |
내 Android 활동이 항상 맨 아래로 스크롤되기 시작하는 이유는 무엇입니까? (0) | 2020.09.12 |
MongoDB GPG-유효하지 않은 서명 (0) | 2020.09.12 |
angular2에서 입력을 비활성화하는 방법 (0) | 2020.09.12 |