# MD5-Hash in Java



## caesarem (29. Aug 2004)

Hallo !

Folgendes Problem:

Ich speichere den MD5-Hash von Benutzerpasswörtern in einer Datenbank. Dabei wird der Hash von der PHP-Funktion md5() erzeugt.

In Java erzeuge ich nun ebenfalls einen MD5-Hash und vergleiche ihn mit dem von PHP erzeugten Hash. Dabei kommt es zu folgendem Fehler:

Enthält der von PHP gelieferte Hash Nullen, so fehlen diese in der Java-Version einfach...

Kann mir diesbezüglich bitte jemand weiterhelfen?

Folgende Funktion nutze ich in Java zum erstellen des Hashs:


```
public String StringToMD5(String str)
  {	
    String r = "";	
    try {
    MessageDigest md = MessageDigest.getInstance( "MD5" );
    byte digest[] = md.digest( str.getBytes() );
    for ( int i = 0; i < digest.length; i++ )
	r = r + ( Integer.toHexString( digest[i]&0xff));
	  } catch (NoSuchAlgorithmException ex) {
      System.err.println(ex.toString());
      System.exit(1);              }
	  return r;
  }
```

mfg
CAESAREM


----------



## foobar (29. Aug 2004)

Das sollte dir weiter helfen http://forum.java.sun.com/thread.jsp?forum=9&thread=531112&tstart=165&trange=15


----------



## caesarem (30. Aug 2004)

Das hilft mir in der Tat. Komisch, dass ich das beim googeln nicht gefunden hab...  :roll: 

Naja, jedenfalls vielen vielen Dank für die schnelle Hilfe !

mfg
CAESAREM


----------



## TheSunToucher (20. Mai 2005)

Ist es auch möglich einen Hash mit einer fixenlänge zu generieren? Ich möchte aus beliebig langen oder auch kurzen Strings Hashcodes erzeugen die immer die gleiche länge haben. 
Gibt es dafür schon was in Java? Sollte ich dafür MD5 benutzen? Kann man überhaupt eine Aussage über die Länge des erzeugten Strings treffen, wenn die maximal Länge bekannt ist, könnte ich die kurzen ja mit Leerzeichen auffüllen...


----------



## mic_checker (20. Mai 2005)

Für MD5 kannst du MessageDigest verwenden, dazu solltest du im Forum aber was finden.


----------



## TheSunToucher (20. Mai 2005)

mic_checker hat gesagt.:
			
		

> Für MD5 kannst du MessageDigest verwenden, dazu solltest du im Forum aber was finden.



Jo, mache ich, ungefähr so wie weiter oben im Thread beschrieben, aber der Hash-String der zurückkommt ist unterschiedlich lang. Ich hätte gern das er beispielsweise immer 40 Zeichen lang ist oder so...


----------



## mic_checker (20. Mai 2005)

Bei "beliebig" langem Input kriegst du ne Prüfsumme fixer Länge....


----------



## TheSunToucher (20. Mai 2005)

Dann mache ich irgendwas falsch:


```
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Test {
	
	public static String string2hash(String text) throws NoSuchAlgorithmException {
		String hash = "";
		MessageDigest md = MessageDigest.getInstance("MD5");
		byte[] digest = md.digest(text.getBytes());
		for ( int i = 0; i < digest.length; i++ ){
			hash += ( Integer.toHexString( digest[i]&0xff)); 
		}
        return hash;
	}

	public static void main(String[] args) throws Exception {
		
		String[] texte = {"dsf", "sdafljkfdhas ksdfhlk hsfdla hlsfhk ls", "", "sdfasd asdkfj f"};
		for (int i = 0; i < texte.length; i++) {
			System.out.println(string2hash(texte[i]) + " -> " + string2hash(texte[i]).length());
		}
	}
}
```


----------



## mic_checker (20. Mai 2005)

Vielleicht kann ich mir deinen Code nachher mal angucken, hab eigentlich keine Zeit mehr. 

Aber es wäre ja nicht im Sinne des Erfinders wenn man z.B. von der Prüfsumme auf die Länge der Original-Nachricht schließen könnte....


----------



## TheSunToucher (20. Mai 2005)

In den meisten Fällen erzeugt das ganze (also der von mir gepostete Code) einen 32 Zeichen langen String, das stimmt mit den 128 bit überein die Md5 zurückliefern soll. Anscheind wird bei der Umwandlung von bits in den String für gewisse Zeichen mehr als ein bit verwendet, den manche Strings in diesem Beispiel erzeugen 29 Zecihen lange Strings... Ich forsche weiter...

Hatte eine Erklärunghier gefunden:
www.leo.org/information/computer/software/bezug/bezug_md5_de.html


----------



## mic_checker (20. Mai 2005)

Hi,
also du verwendest ja Integer.toHexString(...), ich hab da ne andere Methode, mit der auch konstant der 32 Zeichen lange String zurückgegeben wird:


```
public static String toHexString(byte b) {
      int value = (b & 0x7F) + (b < 0 ? 128 : 0);
       String ret = (value < 16 ? "0" : "");
       ret += Integer.toHexString(value).toUpperCase();
       return ret;
     }
```

Diese Methode kannst du in deiner Schleife aufrufen.....sollte eigentlich klappen. Ansonsten sag bitte bescheid.


----------



## mic_checker (21. Mai 2005)

So...jetzt gibts zum Thema auch nen kleinen Beitrag in der FAQ

Sollte mit dem Code geklappt haben oder?


----------



## TheSunToucher (22. Mai 2005)

Danke für deine Hilfe mic_checker,
Wenn ich deine Methode richtig verstehe werden für die bytes die nicht in einem gewissen Bereich liegen "0" eingefügt. Wenn ja, erhöht das nicht die Chance das verschiedene String gleiche Hashs ergeben?

Mal zum Background:
Ich möchte den Hash als "id" eines Datensatzes in einer Datenbank benutzen. Im Datensatz können lange Texte gespeichert werden und wenn man nach denen selektiert wäre das wohl schlecht für die Performance. Also war die Idee den Hash mit abzuspeichern und nach diesem zu selektieren. Da der Hash maximal 32 Zeichen lang ist definiere ich das Feld als CHAR(32). Wenn jetzt ein 29 Zeichen langer Hash erzeugt wird Funktioniert mein Vorhaben trotzdem. Ich hatte die Frage ursprünglich nur gestellt, weil ich bedenken hatte das der Hash zu lang werden könnte, aber jetzt hab ich das System verstanden...

Danke, gruß,
TheSunToucher


----------



## mic_checker (22. Mai 2005)

Nein, das erhöht imho nicht die Chance das es zu Kollisionen kommt. Die Sicherheit beruht ja viel mehr auf der Länge des Hashwerts.

Schließlich stehen die Chancen das du zwei Nachrichten mit dem selben Hashwert findest bei SHA-1 bspw. bei 1 zu 2 hoch 160 (ok, in der Realität wohl eher bei 1 zu 2 hoch 80)....

Du hast ja gesehen was rauskommt wenn man so etwas nicht einbaut, du kriegst u.U. unterschiedlich lange Hashwerte.....wie du im Beitrag (FAQ) auch sehen kannst hat stevq dort noch ne andere "Variante der Ausgabe" gepostet. SOlange du dich immer an ein und die selbe hälst ist das ja auch egal.

Zu deiner Datenbank:
Was ist genau das Problem? Btw. der Hash ist nicht maximal 32 Zeichen lang, sondern genau 32 Zeichen lang (MD5)


----------



## TheSunToucher (22. Mai 2005)

mic_checker hat gesagt.:
			
		

> Zu deiner Datenbank:
> Was ist genau das Problem? Btw. der Hash ist nicht maximal 32 Zeichen lang, sondern genau 32 Zeichen lang (MD5)



Hab kein Problem damit, wollte nur einen fixen Hash haben um ihn in der DB abzuspeichern. Wenn er kürzer wird macht ja nix, wenn er länger werden würde gäbe es ja eine SQLException. Also auch wenn ich die erste hier gepostete Methode verwende und der String manchmal kürzer wird ist das kein Problem.

Also mein Problem ( jedenfalls dieses ;-] ) ist damit gelöst. Ich werd' das so implementieren, danke


----------

