2012-11-30 23 views
5

Başımın arkasındaki bir şey bana burada bariz bir şeyi kaçırdığımı söylüyor.MessageDigest MD5 Algoritma beklediklerimi geri dönmüyor

Varolan bir java projesini, kimlik doğrulama için bir api anahtarının md5 hashını kullanan üçüncü taraf bir api ile tümleştiriyorum. Benim için çalışmıyor ve hata ayıklama sırasında, ürettiklerimdeki karmaların, sağladıkları örneklerle uyuşmadığını fark ettim. Örneklerini kontrol etmek için dizelerden MD5 hash'leri yaratan bazı web siteleri buldum ve yanlış olduğumu söyleyebilirim ve haklılar.

örneğin this website'a göre "merhaba" dizgisi "5d41402abc4b2a76b9719d911017c592" değerinin bir hash'ını üretir. (FWIW Bu web sitesi hakkında hiçbir şey bilmiyorum, ancak benim sahip olduğum örnekleri doğru bir şekilde göremiyorum). Benim kod üzerinden çalıştırdığınızda alıyorum:

XUFAKrxLKna5cZ2REBfFkg == İşte

Ben md5 hash/dize .:

private String md5(String md5Me) throws Exception { 
    MessageDigest md = MessageDigest.getInstance("MD5"); 
    md.reset(); 
    md.update(md5Me.getBytes("UTF-8")); 

    return Base64.encodeBase64String(md.digest()); 
} 
üretmek için kullanıyorum basit yöntemdir

Ben çok kullanılan Geçen hafta SHA1 algoritmasını kullanarak farklı bir API'yi başarıyla doğrulamak için benzer bir yöntem. Sorunun org.apache.commons.net.util.Base64.encodeBase64String ile ilgili olup olmadığını merak ediyorum ... Sadece bazı testlerin byteArray'ın doğru olup olmadığını, ancak dönüştürülen dizenin yanlış olduğunu görmek için herhangi bir yardım büyük beğeni topluyor. .

+1

md.digest() aradığınız baytları içermeli, bunları Base64 algoritmasını kullanarak kodlayın ve farklı sonuç elde edin – hoaz

+0

Bir http isteği için bu baytları bir String'e dönüştürmem gerekiyor, bunu yapmak için daha iyi bir yol var mı ? – eric

+1

new String (byte [] bayt) – Andy

cevap

8

, dize "Merhaba" "5d41402abc4b2a76b9719d911017c592" karmasını oluşturur. (FWIW Bu web sitesi hakkında hiçbir şey bilmiyorum, ancak benim sahip olduğum örnekleri doğru bir şekilde göremiyorum). Benim kod üzerinden çalıştırdığınızda alıyorum:

XUFAKrxLKna5cZ2REBfFkg ==

Her ikisi de aynı onaltı bayt karma temsil doğru yollarıdır. 5d41402abc4b2a76b9719d911017c592, hashın her baytını iki onaltılık basamak olarak gösterir; oysa XUFAKrxLKna5cZ2REBfFkg==, her üç karakter karesinikarakter karesini temsil eder.

bu üçüncü taraf API Beklenen bu onaltılık-versiyonunu üretmek için, bu değiştirebilirsiniz: Buna

Base64.encodeBase64String(md.digest()); 

:

String.format("%032x", new BigInteger(1, md.digest())); 

(çoğunlukla this StackOverflow answer alınan). Bununla birlikte, bunun için bir dış kitaplık kullanmayı düşünebilirsiniz. Yukarıdaki bir yorumda, Perception, Apache Commons DigestUtils'den bahseder. Bunu kullanırsanız, the md5hex method'u isteyeceksiniz.

+0

Sorunumu çözdüğünden, bunu doğru olarak işaretlediğinden, bunun ne olduğunu açıklar ve DigestUtils'i (ayrıca çalışır) kullanma önerisini kullanır. Teşekkürler! – eric

+0

@eric: Rica ederim! – ruakh

2

md5 Karma algoritması, temel java API'sinin bir parçasıdır, dolayısıyla herhangi bir dış kütüphaneye gerek yoktur. İşte bir şifreyi MD5 ile şifrelemek için kullandığım yöntem. bu internet sitesine göre örneğin

import java.security.MessageDigest; 

/** 
* Use to encrypt passwords using MD5 algorithm 
* @param password should be a plain text password. 
* @return a hex String that results from encrypting the given password. 
*/ 
public static String encryptPassword(String password) { 
    try { 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     md.update(password.getBytes()); 

     byte byteData[] = md.digest(); 

     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); 
     } 
     return hexString.toString(); 
    } 
    catch(java.security.NoSuchAlgorithmException missing) { 
     return "Error."; 
    } 
}