[C] SHA-1 Hash in Variable

puckido

Mitglied
Hi,
habe mithilfe der sha1.c (einfach mal :google: n) einen kleinen Code Abschnitt gebastelt der mir den Hash von "string" auf stdout ausgibt.

Der sieht so aus:
Code:
int main(int argc, char **argv) {

int i, j;
SHA1_CTX context;
unsigned char digest[20];
unsigned char final[100];

SHA1Init(&context);
SHA1Update(&context, "string", strlen("string"));
SHA1Final(digest,&context);
for (i = 0; i < 5; i++) {
        for (j = 0; j < 4; j++) {
 printf("%02X", digest[i*4+j]);	    
//strcpy (final,digest[i*4+j]);        
}}
//printf("%c",final);
}

Das gibt mir den richtigen Hash aus. Nun habe ich wie im Kommentar zu sehen versucht das ganze in die Variable "final" zu packen. Irgendwie will das aber nicht. Es kommt jedesmal von gcc:

hello.c: In function ‘main’:
hello.c:33: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
und bei der Ausführung:
Segmentation fault (core dumped)

Irgendwie steh ich grad auf dem Schlauch, was hab ich denn da falsch gemacht :confused:

THX + greets

Os ist Linux + Header Dateien sind alle includet!
 
Zuletzt bearbeitet:
1. muß das heissen:

strcpy (final,&digest[i*4+j]);

Grnd: strcpy erwartet Adressen für Quelle und Ziel, mit dem Index-Zugriff auf digest greifst Du aber auf den Inhalt zu und übergibst strcpy demnach den Inhalt als Adresse, was umgehend zu einem Speicherzugriff führt.

2. Ist strcpy hier falsch. strcpy kopiert digest solange bis es auf einen 0-wert trifft. Da Digest aber Binären Inhalt haben dürfte kopiert strcpy unter Umständen fleißig wild durch den Speicher.

3. Du könntest das z.B. so lösen:

Code:
char* ptr = final;

for (i = 0; i < 5; i++) {
    for (j = 0; j < 4; j++) {
       printf("%02X", digest[i*4+j]);	    
       *ptr++ = digest[i*4+j]
   }
}
*ptr = 0;  // Zeichenkette mti 0 abschließen.
 
Hmm. Also wenn ich meinen Code so umschreibe wie du und dann noch ein:
Code:
printf("%c",ptr);
Gibt er mir immerhin schon ein ? aus, was ja auf binären Inhalt deutet, oder nicht?

Naja, aber wie kriege ich das hin das ich einen ASCII Hash bekomme? Bei
Code:
for (i = 0; i < 5; i++) {
        for (j = 0; j < 4; j++) {
 printf("%02X", digest[i*4+j]);	    
}}

Kommt ja auch ein ASCII Hash heraus :confused:

greets
 
Hmm. Also wenn ich meinen Code so umschreibe wie du und dann noch ein:
Code:
printf("%c",ptr);
Gibt er mir immerhin schon ein ? aus, was ja auf binären Inhalt deutet, oder nicht?

ptr ist eine Adresse,

%c soll aber ein zeichen Ausgeben, also willst Du den Inhalt des Zeigers(ptr). das muß dann heissen:

Code:
printf("%c",*ptr);
 
@isendrow: Deine Lösung ist suboptimal, da Du keinen Speicher für final reservierst, sondern einfach in den Speicher schreibst, wo final gerade hinzeigt.

@puckido:
Ich würde das einfach so machen:
Code:
for (i = 0; i < 5; i++)
  for (j = 0; j < 4; j++)
    printf("%02X", digest[i*4+j]);        

strncpy (final,digest,20);
printf("%c",final);
 
Dann krieg ich wieder nur dieses "?" heraus.. Ich poste euch hier mal kompletten Code:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "sha1.c"

int main(int argc, char **argv) {
int i, j;
SHA1_CTX context;
unsigned char digest[20];
unsigned char final[100];

SHA1Init(&context);
SHA1Update(&context, "string", strlen("string"));
SHA1Final(digest,&context);

for (i = 0; i < 5; i++)
  for (j = 0; j < 4; j++)
    //printf("%02X", digest[i*4+j]);        

strncpy (final,digest,20);
printf("%c",final);

Und hier findet ihr die sha1.c:
Klick mich

Ich habe in meiner sha1.c einfach main() auskommentiert ;)

Nur gehen will es auf keinen Fall :mad:

Irgendwelche Ideen was ich falsch mache?

@jokey2: Er hat sich auf meinen Code oben bezogen, und da ist final schon reserviert!

greets + THX
 
Zuletzt bearbeitet:
der digest vom SHA ist kein string sondern ein binärer buffer.

string sind Zeichenketten mit ASCII-Zeichen im Wertebereich von 32-127 (plus dem ein- oder anderen Steuerzeichen wie 13, 10etc). Ein string wird durch den Wert 0 beendet.

sha erzeugt aber Binäraten im Wertebereich 0 bis 255, also auch jede Menge nicht darstellbare Zeichen.

strncpy ist daher unbrauchbar, weil es aufhört sobald es auf eine 0 trifft, du also keine Garantie hast das tatsächlich 20 Zeichen kopiert werden. Wenn überhaupt mußt du memcpy nehmen.

printf() geht für den digest auch nicht, denn dieser beinhaltet wie gesagt massig nicht-darstellbare Zeichen.

Im original Beispiel verwendet der Autor des SHA daher auch
printf("%02X", digest[i*4+j]);
Womit er den Inhalt des digest Zeichen für Zeichen als 2-stelligen Hexadezimalcode ausgibt.

btw, mit
printf("%c",final);

gibst Du genau ein Zeichen (c wie char) auch, und zwar das erste Zeichen von Final. Um eine ganze Zeichenkette auszugeben müsstest Du
printf("%s",final);
benutzen, was aber in dem Fall auch in die Hos egeht weil in final keine Zeichenkette steht sondern binäre Daten.
 
Und wie kann ich digest nun zu einem String aus 2-stelligen Hexadezimalcodes konvertieren? Wenn du mir das noch sagst bist du mein Tagesheld :p

THX

EDIT:
Also z.b ; b4613f8681b1e26686a2e88299525a4dc89c46d5 - ein SHA1 Hash eben!
 
Zuletzt bearbeitet:
Zurück