Hallo,
ich habe eine Problem mit einem MD5-Prüfsummen-check, aber etwas genauer:
Was ich will:
Sender-Servlet:
- lese eine Datei ein
- bilde von dieser datei die Prüfsumme
- hänge die Prüfsumme an die URL mit an
Empfänger-Servlet:
- lies die Prüfsumme und die Datei ein
- bilde von der eingelesen Datei eine neue Prüfsumme
- vergleiche neue Prüfsumme mit übertragener Prüfsumme auf Gleichheit
Wie versuche ich das zu erreichen:
- Sowohl Sender als auch Empfänger sind auf UTF-8 eingestellt mittels
Code:
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
Desweiteren ist im Tomcat im entsprechenden Connector
Code:
URIEncoding="UTF-8"
eingestellt.
Nun gehe ich bei der Übertragung folgendermaßen vor:
Sender:
Lies (Ascii) Datei ein:
Code:
String fileContent = "";
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(file));
String line;
while((line = bufferedReader.readLine()) != null)
fileContent += line;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Bilde Prüfsumme:
Code:
byte[] checkSum = CommonFunctions.calcChecksum(fileContent);
die Methode calcChecksum sieht hierbei so aus:
Code:
public static byte[] calcChecksum(String fileContent) {
MessageDigest digest = null;
byte[] checkSum = null;
try {
digest = MessageDigest.getInstance("MD5");
digest.update(fileContent.getBytes());
checkSum = digest.digest();
} catch (NoSuchAlgorithmException e) {
logger.error("NoSuchAlgorithmException:");
logger.error(e.getMessage());
logger.error("Stacktrace: ", e);
return null;
}
return checkSum;
}
Eine Beispielchecksumme sieht so aus:
Code:
\ufffdQ\ufffdu\ufffdv\u07a4\u0102\ufffdd\ufffdQ`\ufffd
Hänge checksumme an URL-Parameter:
Code:
urlParamsEncoded += MD5_CHECKSUM + "=" +
URLEncoder.encode(new String(checkSum),"UTF-8")
Empfänger:
Extrahiere Prüfsumme aus den Request-Parametern:
Code:
sentCheckSum = new String(request.getParameter(MD5_CHECKSUM));
Nun bilde ich eine neue Checksumme der übertragenen Datei, die so aussieht:
Code:
\ufffdQ\ufffdu\ufffdv\u07a4\u0102\ufffdd\ufffdQ`\ufffd
Dies ist genau die gleiche Prüfsumme, die beim Sender gebildet wurde.
Nun vergleiche ich die Checksummen:
Code:
MessageDigest.isEqual(newCheckSum, sentCheckSum))
Das Problem nun:
Der isEqual()-Test schlägt, obwohl die Checksummen ja identisch sind.
Bilde ich jedoch aus den beiden checksummen zwei Strings und vergleiche die mit der
equals()-Methode kommt raus, das die beiden gleich sind (das wäre auch wirklich merkwürdig
gewesen, wenn der Test fehlgeschlagen wäre).
Nun hab ich mir mal die einzelnen Zeichen der Checksummen angesehen und ein wenig gegoogelt danach.
Auffallend ist ja das fast nur das Zeichen
vorkommt.
Google sagt dazu:
b) the '/ufffd' is a java escape code for a unicode character - you
should be able to convert it to UTF-8 using a string constructor like
'new String("/ufffd random stuff", "UTF-8")'.
Soweit sieht das dann doch alles korrekt aus?
Also nochmal kurz zusammengefaßt:
verschickte Prüfsumme == empfangen Prüfsumme == neue Prüfsumme
=> Prüfsummen-Vergleich schlägt
=> String.equals() bestätigt mir aber was ich sehe, nämlich das sie gleich sind
Any ideas?
Ich verstehe das nicht so ganz, die Strings sind doch identisch, warum klappt das mit dem digest nicht?
Lesezeichen