MD5 hash aus string erstellen



  • Nabend zusammen,

    bin momentan noch dabei C zu lernen, momentan möchte ich ein kleines testprogramm
    schreiben, allerdings soll nun ein md5 hash aus einem string erstellt werden.

    Dazu habe ich nach header bzw libs gegoogelt, dabei bin ich auf http://www.ietf.org/rfc/rfc1321.txt gestossen.
    Ich habe mir daraus eine static library erstellt(libmd5.a).

    Jedoch bringt mir der compiler eine Fehlermeldung:

    error: unknown type name 'MD5_CTX'
    

    Ich verwende dabei diesen Code:

    char *str2md5(const char *str, int length) {
        int n;
        MD5_CTX c;
        unsigned char digest[16];
        char *out = (char*)malloc(33);
    
        MD5_Init(&c);
    
        while (length > 0) {
            if (length > 512) {
                MD5_Update(&c, str, 512);
            } else {
                MD5_Update(&c, str, length);
            }
            length -= 512;
            str += 512;
        }
    
        MD5_Final(digest, &c);
    
        for (n = 0; n < 16; ++n) {
            snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
        }
    
        return out;
    }
    

    Als IDE verwende ich Codeblocks für Windows(MinGW) und Linux(Debian, Ubuntu).

    Verstehe ich den sinn einer statischen bibliothek falsch oder mach ich es zu kompliziert?

    Bin für jede hilfe dankbar

    Grüsse Spirit


  • Mod

    Spirit/BLACKDIAMONT schrieb:

    Verstehe ich den sinn einer statischen bibliothek falsch oder mach ich es zu kompliziert?

    Das ist ein Compilerfehler, der passiert lange bevor die Bibliothek auch überhaupt nur gesucht wird. Klingt nach einem fehlenden Include oder anderem Fehler bei der Benutzung der Bibliothek (Bibliothek im Sinne des Gesamtpakets, nicht die statische Bibliotheksdatei).

    Da sind auch noch andere Sachen in dem Code falsch. Zeichenketten gibt man nicht so aus Funktionen zurück. Es wird zwar technisch gesehen funktionieren, aber du lädst mit dem Design Speicherlöcher und und andere Fehler geradezu ein. Mach es besser so wie beispielsweise das MD5_Final.



  • Moin,

    danke für deine Antwort, den code snippet hab ich von http://stackoverflow.com/questions/7627723/how-to-create-a-md5-hash-of-a-string-in-c

    Habe leider keine beispiele gefunden einen md5 hash zu berechnen(ewig gesucht).

    Das ist ein Compilerfehler, der passiert lange bevor die Bibliothek auch überhaupt nur gesucht wird. Klingt nach einem fehlenden Include oder anderem Fehler bei der Benutzung der Bibliothek

    Wenn ich dich richtig verstehe scheitert der compiler an dem code "MD5_CTX c;",
    hat aber die statische biblio noch nicht geladen? 😕


  • Mod

    Spirit/BLACKDIAMONT schrieb:

    Wenn ich dich richtig verstehe scheitert der compiler an dem code "MD5_CTX c;",
    hat aber die statische biblio noch nicht geladen? 😕

    Compiler laden keine Bibliotheken. Compiler übersetzen Code in Maschinenanweisungen. Dazu müssen sie bloß wissen, wie die Objekte im Code "beschaffen" sind (Deklaration im Header. Analogie: So etwas wie die Form eines Puzzleteils), nicht wie der Maschinencode zu diesen Dingen aussieht (das steht in der Bibliotheksdatei. Analogie: Was auf einem Puzzleteil zu sehen ist). Erst der Linker setzt nach der Übersetzung verschiedene Maschinencodeteile zu einem vollständigen Programm zusammen (Analogie: Löst das Puzzle. Da der Compiler schon wusste, wie die Teile von der Form her aussehen sollen, passen alle Teile zusammen.)

    Hier fehlt Information darüber, was MD5_CTX ist. Das sollte gewöhnlicherweise in einem Header stehen. Zeig mal einen vollständigen Quelltext, der diesen Fehler aufweist. Dann kann man dir sagen, was fehlt.

    danke für deine Antwort, den code snippet hab ich von http://stackoverflow.com/questions/7627723/how-to-create-a-md5-hash-of-a-string-in-c

    Nicht ohne einen Schuss Selbstironie: Nicht alles was man so im Internet liest, besonders in öffentlichen Foren, ist richtig oder gar gut. 😉



  • danke für die erklärung 🙂

    Jetzt versteh ich wie kompiliervorgang abläuft.

    Zeig mal einen vollständigen Quelltext, der diesen Fehler aufweist. Dann kann man dir sagen, was fehlt

    Das snippet wirft den code, der rest im programm wird ohne fehler und warnungen sauber verarbeitet.

    Kann dir gerne mal den kompletten code posten(ist allerdings etwas groß):

    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <time.h>
    #ifdef __unix__
    # include <unistd.h>
    #elif defined _WIN32
    # include <windows.h>
    #endif
    #define for_each_item(item, list) \
        for(T * item = list->head; item != NULL; item = item->next)
    
    void ende() {
    printf("Programm Ende. Beliebige Taste um das Men\x81 anzuzeigen . . .");
    getch();
    }
    void perr_exit(char* msg, int ret_code)
    {
      printf("%s, Error: ",msg);
      printf("%d\n",ret_code);
      exit(ret_code);
    }
    
    char *str2md5(const char *str, int length) {
        int n;
        MD5_CTX c;
        unsigned char digest[16];
        char *out = (char*)malloc(33);
    
        MD5_Init(&c);
    
        while (length > 0) {
            if (length > 512) {
                MD5_Update(&c, str, 512);
            } else {
                MD5_Update(&c, str, length);
            }
            length -= 512;
            str += 512;
        }
    
        MD5_Final(digest, &c);
    
        for (n = 0; n < 16; ++n) {
            snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
        }
    
        return out;
    } 
    
    int programm2() {
        char temp;
        char passwort[10];
        int index = 0;
        while((temp = getch()) != 13)
        {
            printf("*");
            passwort[index++] = temp;
            passwort[index] = '\0';
        }
        printf("\nDu hast eingegeben: %s\n",passwort);
    return 0;
    }
    char* programm1(char header[], char content[]) {
    char* url;
      char* site;
      char* host;
      int  conlengh;
      char  send_buf[256];
      char  recv_buf[256];
      long  rc;
      FILE* target_file;
      int   writeoutputtofile = 0; //debugging only!
      char  uses_file=0;
      char* write_ptr;
      char  ausgabe[256];
      SOCKET s;
      SOCKADDR_IN addr;
      WSADATA wsa;
      HOSTENT* hent;
      if(WSAStartup(MAKEWORD(2,0),&wsa))
      perr_exit("WSAStartup failed",WSAGetLastError());
      addr.sin_family=AF_INET;
      addr.sin_port=htons(80);
      char buf[] = { "bastelecke.mystic-welten.de/api.php" };
      url=buf;
      if(strncmp("http://",url,7)==0)
        host=url+7;
      else
        host=url;
    
      if((site=strchr(host,'/'))!=0)
        *site++='\0';
      else
        site=host+strlen(host); /* \0 */
    
      if(writeoutputtofile) {
        if(!(target_file=fopen("output.txt","w")))
            {
            printf("Cannot open File ");
            perr_exit("output.txt",GetLastError());
            }
            uses_file=1;
        }
    
      printf("Host: %s\n",host);
      printf("Site: %s\n",site);
      printf("Connecting....\n");
    
      if((addr.sin_addr.s_addr=inet_addr(host))==INADDR_NONE)
      {
        if(!(hent=gethostbyname(host)))
          perr_exit("Cannot resolve Host",WSAGetLastError());
    
        strncpy((char*)&addr.sin_addr.s_addr,hent->h_addr,4);
    
        if(addr.sin_addr.s_addr==INADDR_NONE)
          perr_exit("Cannot resolve Host",WSAGetLastError());
      }
    
      if((s=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
        perr_exit("Cannot create Socket",WSAGetLastError());
    
      if( connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)))
        perr_exit("Cannot connect",WSAGetLastError());
        conlengh = strlen(content);
      printf("Connected to %s...\n",host);
      sprintf(send_buf,header,site,host,conlengh,content);
    
      if((send(s,send_buf,strlen(send_buf),0))<strlen(send_buf))
        perr_exit("Cannot send Data",WSAGetLastError());
    
      while((rc=recv(s,recv_buf,255,0))>0)
      {
        recv_buf[rc]='\0';
        if(uses_file)
        {
          if(uses_file==1)
          {
            /* web server info nicht in Datei speichern */
            if((write_ptr=strstr(recv_buf,"\x0D\x0A\x0D\x0A"))>0)
            {
              uses_file=2;
              write_ptr+=4;
            }
          }
          else
            write_ptr=recv_buf;
          if(uses_file==2)
          {
            if( fwrite(write_ptr,1, rc-(write_ptr-recv_buf), target_file)<rc-(write_ptr-recv_buf))
              fclose(target_file);
          }
        }
        else /* uses_file */
          printf("%s\n",recv_buf);
          strcpy(ausgabe,strstr(recv_buf,"\x0D\x0A\x0D\x0A"));
          //printf("%s\n",ausgabe); //debuggin only
      }
        if(uses_file)
        fclose(target_file);
        closesocket(s);
        char* ret;
        ret = (char *) malloc(strlen(ausgabe)); //speicherbereich dynamisch anlegen
        strcpy(ret, ausgabe);
    return ret;
    }
    int main(int argc, char *argv[])
    {
        int Eingabe;
        while(Eingabe != 99) {
            printf("Getchi Console - WebLogin V0.1\n");
            printf("\n\n- Hauptmen\x81 -\n\n<1>\n<2>\n<3>\n<4>\n<5>\n<6>\n<7>\n<8>\n<9>Beenden\n\nMen\x81: < >\b\b");
            scanf("%d",&Eingabe);
            fflush(stdin);
            printf("\n\n");
            switch(Eingabe) {
                case 1:
                printf("Nr.1\n");
                char* version = programm1("POST /%s HTTP/1.1\nHost: %s\nUser-Agent: Web\nContent-Type: application/x-www-form-urlencoded\nContent-Length: %d\nConnection: close\n\n%s", "action=version");
                if(strstr(version,"1.0.0.5")) {
                printf("Programm Aktuell");
                }
                printf("\n");
                ende();
                system("Cls");
                break;
                case 2:
                printf("Nr.2\n");
                char* userexist =  programm1("POST /%s HTTP/1.1\nHost: %s\nUser-Agent: Web\nContent-Type: application/x-www-form-urlencoded\nContent-Length: %d\nConnection: close\n\n%s", "action=login&user=test");
                printf("%s\n",userexist);
                printf("\n");
                ende();
                system("Cls");
                break;
                case 3:
                printf("Nr.3\n");
                printf("\n");
                ende();
                system("Cls");
                break;
                case 4:
                printf("Nr.4\n");
                printf("\n");
                ende();
                system("Cls");
                break;
                case 5:
                printf("Nr.5\n");
                Sleep(100);
                printf("\n");
                ende();
                system("Cls");
                break;
                case 6:
                printf("Nr.6\n");
                printf("\n");
                ende();
                system("Cls");
                break;
                case 7:
                printf("Nr.7\n");
                printf("\n");
                ende();
                system("Cls");
                break;
                case 8:
                printf("Nr.8\n");
                printf("\n");
                ende();
                system("Cls");
                break;
                case 9:
                exit(0);
                break;
                default:
                printf("Falsche Eingabe! <%d>\n",Eingabe);
                ende();
                system("Cls");
            }
        }
    return 0;
    }
    

    Linker: libws2_32.a libmd5.a



  • Du musst in deinem Quellcode die Bibliothek als header einbinden:

    #include "libmd5.h"
    


  • Nirvash schrieb:

    Du musst in deinem Quellcode die Bibliothek als header einbinden:

    #include "libmd5.h"
    

    Das musst du mir mal erklären Oo, ich habe die bibliothek im linker eingetragen woher den header nehmen? 😕


  • Mod

    #include <md5.h>



  • ok, ich habe die md5.h von openssl genommen.
    Ohne Erfolg, obwohl es im header deklariert wird 😕

    Wenn ich die md5.h mit der ich die library erstellt habe (link im ersten post), es versuche gibts folgende fehler:

    D:\md5 c\md5.h|29|error: unknown type name 'UINT4'|
    D:\md5 c\md5.h|30|error: unknown type name 'UINT4'|
    D:\md5 c\md5.h|34|error: expected '=', ',', ';', 'asm' or '__attribute__' before 'PROTO_LIST'|
    D:\md5 c\md5.h|35|error: expected '=', ',', ';', 'asm' or '__attribute__' before 'PROTO_LIST'|
    D:\md5 c\md5.h|37|error: expected '=', ',', ';', 'asm' or '__attribute__' before 'PROTO_LIST'|
    Z:\Spirit\Documents\cpp projekte\weblogin\main.c||In function 'str2md5':|
    Z:\Spirit\Documents\cpp projekte\weblogin\main.c|33|warning: implicit declaration of function 'MD5_Init' [-Wimplicit-function-declaration]|
    Z:\Spirit\Documents\cpp projekte\weblogin\main.c|37|warning: implicit declaration of function 'MD5_Update' [-Wimplicit-function-declaration]|
    Z:\Spirit\Documents\cpp projekte\weblogin\main.c|45|warning: implicit declaration of function 'MD5_Final' [-Wimplicit-function-declaration]|
    ||=== Build finished: 5 errors, 3 warnings (0 minutes, 0 seconds) ===|
    

    Ist das so schwer md5 zu integrieren 😮


  • Mod

    Erstell doch mal ein möglichst kurzes Minimalbeispiel. Dieses zeigst du uns vollständig mit den genauen Fehlermeldungen.



  • Sorry für den grossen aufwand den ich verursacht habe, der Fehler wurde gefunden 🙄
    Ich habe im code immer "MD5_Init" vom beispiel verwendet ohne zu schauen ob das überhaupt stimmt, es wird nämlich "MD5Init" geschrieben und der code funktioniert 😮

    Den code werde ich trozdem nochmal überprüfen auf die schwachstellen die SeppJ genannt hatte(Design, Speicherlöcher).

    Wünsche noch einen schönen Sonntag!

    Grüsse Spirit


Anmelden zum Antworten