Cyberpython Online

MD5 checksums

Posted in C#, Debian, Linux, Ubuntu, java, programming, Προγραμματισμός by cyberpython on Οκτωβρίου 4, 2008

Πολλοί θα έχετε παρατηρήσει όταν κατεβάζετε αρχεία από το Internet οτι συνήθως συνοδεύονται από μία “περίεργη” ακολουθία αριθμών και γραμμάτων (στην πραγματικότητα είναι ένας αριθμός σε δεκαεξαδική μορφή) με το όνομα MD5 sum. Τί είναι όμως αυτό το MD5 checksum;

Checksum είναι το άθροισμα ελέγχου δηλαδή ένας αριθμός που προκύπτει από την επεξεργασία μίας ακολουθίας (π.χ. ενός αρχείου, αφού κάθε αρχείο είναι μία ακολουθία από bytes). Το άθροισμα ελέγχου μας βοηθά να διαπιστώσουμε αν η ακολουθία (το αρχείο στη δική μας περίπτωση) που έχουμε είναι ίδια με την ακολουθία στην οποία αντιστοιχεί το checksum που ελέγχουμε.

Ο πιο διαδεδομένος τρόπος υπολογισμού checksums είναι με χρήση κρυπτογραφικών μεθόδων όπως η MD5, η SHA-1 και άλλες. Αυτό οφείλεται στο οτι αυτές οι μέθοδοι παίρνουν σαν είσοδο μία ακολουθία οποιουδήποτε μήκους (π.χ. μία γραμμή με 1-2 λέξεις ή ένα αρχείο πολλών GB) και δίνουν σαν αποτέλεσμα ένα αριθμό σταθερού μήκους. Επίσης, το πιο σημαντικό χαρακτηριστικό τους είναι οτι για την ίδια ακολουθία πάντοτε δίνουν την ίδια έξοδο – οπότε αν το αρχείο που έχουμε είναι σωστό τότε η μέθοδος θα μας δώσει το ίδιο checksum με αυτό που χρησιμοποιούμε ως σημείο αναφοράς.

Για παράδειγμα για το κείμενο “Καλημέρα! Τί κάνετε;” η MD5 δίνει πάντα το αποτέλεσμα: “050212838868975b42ed774c9ac4d8e6″

Η MD5 είναι η προτιμώμενη συνάρτηση για τον έλεγχο αρχείων κυρίως λόγω της ταχύτητας υπολογισμού και της σχετικής απλότητάς της. Όμως, το 2005 αποδείχθηκε οτι υπάρχουν σοβαρά προβλήματα  στη συγκεκριμένη συνάρτηση που μπορούν να οδηγήσουν στη δημιουργία του ίδιου hash για διαφορετικές ακολουθίες εισόδου (Arjen Lenstra, Xiaoyun Wang, Benne de Weger – Μάρτιος 2005) και το 2006 παρουσιάστηκε και ένας αλγόριθμος για την παραγωγή τους σε λιγότερο από ένα λεπτό (Vlastimil Klima – Μάρτιος 2006) !!!

Παρ’ όλα αυτά η μέθοδος MD5 εξακολουθεί να χρησιμοποιείται ευρέως (ακόμη και για την αποθήκευση κωδικών).

Για να βρούμε το MD5 hash ενός αρχείου σε Linux ανοίγουμε ένα τερματικό και δίνουμε την εντολή:

md5sum όνομα_αρχείου

και θα μας εμφανίσει το άθροισμα md5 του αρχείου.

Σε περιβάλλον Windows θα πρέπει να χρησιμοποιήσουμε κάποια third-party εφαρμογή όπως το MD5Summer.

Μία απλή υλοποίηση σε Java είναι η παρακάτω:

package com.wordpress.cyberpython;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SimpleMD5 {

    public SimpleMD5(){

    }

    public String generateChecksum(String filename){

        try{
            MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
            DigestInputStream digIn = new DigestInputStream(new FileInputStream(filename), digest);    

            while(digIn.read() != -1){
            }

            byte[] checksum = digest.digest();

            printToHex(checksum);
            System.out.println("  "+(new File(filename)).getName());

            digIn.close();
        }
        catch(FileNotFoundException fnfe){
            System.err.println(fnfe.toString());
        }
        catch(IOException ioe){
            System.err.println(ioe.toString());
        }
        catch(NoSuchAlgorithmException nsae){
            System.err.println(nsae.toString());
        }

        return "Could not calculate MD5 sum!";

    }

    private void printToHex(byte[] bytes){

        int a;
        String tmp;
        for(int i=0; i<bytes.length; i++){
            a = bytes[i] & 0xFF;
            tmp = Integer.toHexString(a);
            if(tmp.length()==1){
                tmp = "0"+tmp;
            }
            System.out.print(tmp);
        }
    }

    public static void main(String[] args) {
            if(args.length!=1){
                System.err.println("Usage is:\n java SimpleMD5 <input_file>");
                System.exit(1);
            }

            SimpleMD5 md5 = new SimpleMD5();
            md5.generateChecksum(args[0]);
    }

}

UPDATE:

Και το (σχεδόν) αντίστοιχο σε C#:

(Προσοχή: Το παρακάτω πρόγραμμα πριν τον υπολογισμό του MD5 sum φορτώνει ολόκληρο το αρχείο στη μνήμη, οπότε δεν ενδύκνειται για μεγάλα αρχεία!!!)

// md5.cs created with MonoDevelop
// User: cyberpython at 3:59 Μ 4/10/2008
//

using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;

namespace CSharpMD5
{

    public class SimpleMD5
    {

        public SimpleMD5(){

        }

        public void generateChecksum(string filename){

            byte[] input = File.ReadAllBytes(filename);

            MD5 md5 = MD5.Create();

            byte[] hash = md5.ComputeHash(input);

            StringBuilder checksum = new StringBuilder();

            for (int i = 0; i < hash.Length; i++)
            {
                checksum.Append(hash[i].ToString(”x2″));
            }

            FileInfo fileInfo = new FileInfo(filename);

            System.Console.Out.WriteLine(checksum.ToString() + “  “+fileInfo.Name);

        }

        static void Main(String[] args){

            if(args.Length != 1){
                System.Console.Error.WriteLine(”Usage is:\n SimpleMD5.exe <input file>”);
                Environment.Exit(1);
            }

            SimpleMD5 md5 = new SimpleMD5();

            md5.generateChecksum(args[0]);

        }

    }
}

Υποβολή απάντησης