C String Problem

MCStreetguy

Stammuser
Hey Leute ich versuche grade in meinem Header eine Funktion zu schreiben die einen String in Integer-Werte umwandelt und als char* zurückgibt...
Code:
char* strHash(char in[])
{
     int end = strlen(in), i = 0, pos = i;
     while(i<end)
     {
          switch(in[i])
          {
                       case 'a': out[pos] = '0'; break;
                       case 'A': out[pos] = '1'; break;
                       case 'b': out[pos] = '2'; break;
                       case 'B': out[pos] = '3'; break;
                       case 'c': out[pos] = '4'; break;
                       case 'C': out[pos] = '5'; break;
                       case 'd': out[pos] = '6'; break;
                       case 'D': out[pos] = '7'; break;
                       case 'e': out[pos] = '8'; break;
                       case 'E': out[pos] = '9'; break;
                       case 'f': out[pos] = '1'; pos ++; out[pos] = '0'; break;
                       case 'F': out[pos] = '1'; pos ++; out[pos] = '1'; break;
                       case 'g': out[pos] = '1'; pos ++; out[pos] = '2'; break;
                       case 'G': out[pos] = '1'; pos ++; out[pos] = '3'; break;
                       case 'h': out[pos] = '1'; pos ++; out[pos] = '4'; break;
                       case 'H': out[pos] = '1'; pos ++; out[pos] = '5'; break;
                       case 'i': out[pos] = '1'; pos ++; out[pos] = '6'; break;
                       case 'I': out[pos] = '1'; pos ++; out[pos] = '7'; break;
                       case 'j': out[pos] = '1'; pos ++; out[pos] = '8'; break;
                       case 'J': out[pos] = '1'; pos ++; out[pos] = '9'; break;
                       case 'k': out[pos] = '2'; pos ++; out[pos] = '0'; break;
                       case 'K': out[pos] = '2'; pos ++; out[pos] = '1'; break;
                       case 'l': out[pos] = '2'; pos ++; out[pos] = '2'; break;
                       case 'L': out[pos] = '2'; pos ++; out[pos] = '3'; break;
                       case 'm': out[pos] = '2'; pos ++; out[pos] = '4'; break;
                       case 'M': out[pos] = '2'; pos ++; out[pos] = '5'; break;
                       case 'n': out[pos] = '2'; pos ++; out[pos] = '6'; break;
                       case 'N': out[pos] = '2'; pos ++; out[pos] = '7'; break;
                       case 'o': out[pos] = '2'; pos ++; out[pos] = '8'; break;
                       case 'O': out[pos] = '2'; pos ++; out[pos] = '9'; break;
                       case 'p': out[pos] = '3'; pos ++; out[pos] = '0'; break;
                       case 'P': out[pos] = '3'; pos ++; out[pos] = '1'; break;
                       case 'q': out[pos] = '3'; pos ++; out[pos] = '2'; break;
                       case 'Q': out[pos] = '3'; pos ++; out[pos] = '3'; break;
                       case 'r': out[pos] = '3'; pos ++; out[pos] = '4'; break;
                       case 'R': out[pos] = '3'; pos ++; out[pos] = '5'; break;
                       case 's': out[pos] = '3'; pos ++; out[pos] = '6'; break;
                       case 'S': out[pos] = '3'; pos ++; out[pos] = '7'; break;
                       case 't': out[pos] = '3'; pos ++; out[pos] = '8'; break;
                       case 'T': out[pos] = '3'; pos ++; out[pos] = '9'; break;
                       case 'u': out[pos] = '4'; pos ++; out[pos] = '0'; break;
                       case 'U': out[pos] = '4'; pos ++; out[pos] = '1'; break;
                       case 'v': out[pos] = '4'; pos ++; out[pos] = '2'; break;
                       case 'V': out[pos] = '4'; pos ++; out[pos] = '3'; break;
                       case 'w': out[pos] = '4'; pos ++; out[pos] = '4'; break;
                       case 'W': out[pos] = '4'; pos ++; out[pos] = '5'; break;
                       case 'x': out[pos] = '4'; pos ++; out[pos] = '6'; break;
                       case 'X': out[pos] = '4'; pos ++; out[pos] = '7'; break;
                       case 'y': out[pos] = '4'; pos ++; out[pos] = '8'; break;
                       case 'Y': out[pos] = '4'; pos ++; out[pos] = '9'; break;
                       case 'z': out[pos] = '5'; pos ++; out[pos] = '0'; break;
                       case 'Z': out[pos] = '5'; pos ++; out[pos] = '1'; break;
                       default: out[i] = in[i]; break;
          }
          i ++;
          pos ++;
     }
     out[pos+1]='\0';
     return out;
}
(out ist im als globale Variable im Kopfteil des Header deklariert)


Wenn ich das ganze aber jetzt aufrufe indem ich
Code:
#include<ext\hash.h>

int main()
{
    char in[500];
    int i;
    scanf("%s",in);
    printf(strHash(in));
    fflush(stdin);
    getchar();
    return 0;
}
ausführen lasse, liest er immer nur ein Wort ein...
Wenn ich das %s aber zum Beispiel durch ein %100c ersetze wartet er bis ich exakt 100 Zeichen eingegeben habe :/
Wie kann ich also den String einlesen ohne das er beim ersten Whitespace abbricht?

Danke schonmal, MCStreetguy
 

benediktibk

Standardgruppe für nicht aktivierte User
fgets anstelle von scanf, das kann auch Leerzeichen, und im default-Zweig den richtigen Index für out verwenden:

Code:
#include <stdio.h>
#include <string.h>

const unsigned int bufferSize = 500;
char out[bufferSize*2];

char* strHash(char in[])
{
     int end = strlen(in), i = 0, pos = i;
     while(i<end)
     {
          switch(in[i])
          {
                       case 'a': out[pos] = '0'; break;
                       case 'A': out[pos] = '1'; break;
                       case 'b': out[pos] = '2'; break;
                       case 'B': out[pos] = '3'; break;
                       case 'c': out[pos] = '4'; break;
                       case 'C': out[pos] = '5'; break;
                       case 'd': out[pos] = '6'; break;
                       case 'D': out[pos] = '7'; break;
                       case 'e': out[pos] = '8'; break;
                       case 'E': out[pos] = '9'; break;
                       case 'f': out[pos] = '1'; pos ++; out[pos] = '0'; break;
                       case 'F': out[pos] = '1'; pos ++; out[pos] = '1'; break;
                       case 'g': out[pos] = '1'; pos ++; out[pos] = '2'; break;
                       case 'G': out[pos] = '1'; pos ++; out[pos] = '3'; break;
                       case 'h': out[pos] = '1'; pos ++; out[pos] = '4'; break;
                       case 'H': out[pos] = '1'; pos ++; out[pos] = '5'; break;
                       case 'i': out[pos] = '1'; pos ++; out[pos] = '6'; break;
                       case 'I': out[pos] = '1'; pos ++; out[pos] = '7'; break;
                       case 'j': out[pos] = '1'; pos ++; out[pos] = '8'; break;
                       case 'J': out[pos] = '1'; pos ++; out[pos] = '9'; break;
                       case 'k': out[pos] = '2'; pos ++; out[pos] = '0'; break;
                       case 'K': out[pos] = '2'; pos ++; out[pos] = '1'; break;
                       case 'l': out[pos] = '2'; pos ++; out[pos] = '2'; break;
                       case 'L': out[pos] = '2'; pos ++; out[pos] = '3'; break;
                       case 'm': out[pos] = '2'; pos ++; out[pos] = '4'; break;
                       case 'M': out[pos] = '2'; pos ++; out[pos] = '5'; break;
                       case 'n': out[pos] = '2'; pos ++; out[pos] = '6'; break;
                       case 'N': out[pos] = '2'; pos ++; out[pos] = '7'; break;
                       case 'o': out[pos] = '2'; pos ++; out[pos] = '8'; break;
                       case 'O': out[pos] = '2'; pos ++; out[pos] = '9'; break;
                       case 'p': out[pos] = '3'; pos ++; out[pos] = '0'; break;
                       case 'P': out[pos] = '3'; pos ++; out[pos] = '1'; break;
                       case 'q': out[pos] = '3'; pos ++; out[pos] = '2'; break;
                       case 'Q': out[pos] = '3'; pos ++; out[pos] = '3'; break;
                       case 'r': out[pos] = '3'; pos ++; out[pos] = '4'; break;
                       case 'R': out[pos] = '3'; pos ++; out[pos] = '5'; break;
                       case 's': out[pos] = '3'; pos ++; out[pos] = '6'; break;
                       case 'S': out[pos] = '3'; pos ++; out[pos] = '7'; break;
                       case 't': out[pos] = '3'; pos ++; out[pos] = '8'; break;
                       case 'T': out[pos] = '3'; pos ++; out[pos] = '9'; break;
                       case 'u': out[pos] = '4'; pos ++; out[pos] = '0'; break;
                       case 'U': out[pos] = '4'; pos ++; out[pos] = '1'; break;
                       case 'v': out[pos] = '4'; pos ++; out[pos] = '2'; break;
                       case 'V': out[pos] = '4'; pos ++; out[pos] = '3'; break;
                       case 'w': out[pos] = '4'; pos ++; out[pos] = '4'; break;
                       case 'W': out[pos] = '4'; pos ++; out[pos] = '5'; break;
                       case 'x': out[pos] = '4'; pos ++; out[pos] = '6'; break;
                       case 'X': out[pos] = '4'; pos ++; out[pos] = '7'; break;
                       case 'y': out[pos] = '4'; pos ++; out[pos] = '8'; break;
                       case 'Y': out[pos] = '4'; pos ++; out[pos] = '9'; break;
                       case 'z': out[pos] = '5'; pos ++; out[pos] = '0'; break;
                       case 'Z': out[pos] = '5'; pos ++; out[pos] = '1'; break;
                       default: out[pos] = in[i]; break;
          }
          i ++;
          pos ++;
     }
     out[pos+1]='\0';
     return out;
}

int main()
{
    char in[bufferSize];
    int i;
    fgets(in, bufferSize, stdin);
    printf("%s\n", in);
    printf(strHash(in));
    fflush(stdin);
    getchar();
    return 0;
}

So scheint es zumindest zu funktionieren. Schön ist es aber trotzdem nicht.

mfg benediktibk
 

MCStreetguy

Stammuser
Hmm das mit fgets versuche ich mal...


Es ist zu nix gut, nur ich wollte es selbst programmieren...
Klar gibt es massenhaft Hash-Funktionen, aber ich will es nicht benutzen sondern programmieren :)
 

benediktibk

Standardgruppe für nicht aktivierte User
Nur ist das kein sonderlich guter Hash, weil er
  • ein bis zweimal solange wie die Quelle ist
  • die Änderung von einem Zeichen in der Quelle zur Änderung von ein bis zwei Zeichen im Hash führt
  • bijektiv ist (wenn man nur Buchstaben als Urbild verwendet)

mfg benediktibk
 
Zuletzt bearbeitet:

usoya

New member
Hmm das mit fgets versuche ich mal...


Es ist zu nix gut, nur ich wollte es selbst programmieren...
Klar gibt es massenhaft Hash-Funktionen, aber ich will es nicht benutzen sondern programmieren :)
Verstehe dich. Wie wäre es wenn du den md2 Quellcode von OpenSSL nimmst und diese studierst. Anschliessend auf Basis diesem einfachen Hash deine eigene Vorstellung einfliessen lässt? Dadurch lernst du wie erfahrene Entwickler die Hash implementiert haben und kreierst auf bestehendem was neues. Mittels erpropten C/OpenSSL Funktionen.
 

benediktibk

Standardgruppe für nicht aktivierte User
Das kommt ganz darauf an, was du für Ansprüche hast. Wenn du die Funktion im Bereich von Kryptografie einsetzen willst würde ich zumindest MD5 vorschlagen. Falls du allerdings nur eine Funktion für eine Hashtabelle benötigst und ausreichend lange Zeichenketten in der Regel vorliegen könnte auch schon etwas in der Art ausreichen:
Code:
sum <- 0
for i = 1 to length(string)
   zeichenCode <- 0
   if string(i) is upper case then
      zeichenCode <- ASCII(string(i)) - 65
   else then
      zeichenCode <- ASCII(string(i)) - 97
   end if
   sum <- sum + zeichenCode*26^(i - 1)
end for
hash <- sum mod p
Wobei du dir für p eine nette Primzahl aussuchst. Mit der kannst du dann den Bereich festlegen, in dem der Hash schlussendlich liegt (von 0 bis p-1).

Das alles natürlich ohne Gewähr. Wahrscheinlich prügelt mich eh gleich ein Informatiker :D, aber der darf dann gerne einen besseren Vorschlag machen. Ich lerne immer gerne was dazu.

Wobei die ultimative Frage natürlich ist, wozu du die Hash-Funktion brauchst.

mfg benediktibk
 

MCStreetguy

Stammuser
Das ganze sollte schon als Kryptologische Funktion genutzt werden...
Ich hatte vor ein Programm mit Login zu schreiben und wenn die Passwörter im Klartext abgespeichert werden, ist es ja nicht mehr schwierig sich anzumelden...

Kann man MD5 auch in C umsetzen?
Weil der Pseudo-Code von Wikipedia hat mir nicht sehr weitergeholfen für die Umsetzung in C... :/
 

benediktibk

Standardgruppe für nicht aktivierte User
Für den Zweck sollte deine Hash-Funktion mal zumindest nicht bijektiv sein, ansonsten kann man aus dem Hash wieder auf das Passwort rückschließen. Falls du es nicht selber implementieren willst, dafür gibts Libraries wie Sand am Meer:
A portable, fast, and free implementation of the MD5 Message-Digest Algorithm (RFC 1321) [Openwall Community Wiki]
MD5 - Rosetta Code

Wenn du es selber machen willst bleibt dir wohl nur der Pseudo-Code von Wikipedia (oder ähnliches) über. Wo liegt denn das Problem genau, weil an sich ist die Beschreibung eh sehr detailliert.

mfg benediktibk

Edit: Sicherer wäre zum Beispiel SHA2
 
Zuletzt bearbeitet:

CDW

Moderator
Mitarbeiter
@benediktibk:
auf
All English words
losgelassen (Wortliste extrahiert, whitespaces gestrippt, uppercase belassen),
gibt es für 214553 Wörter:
P= 214559 collisions: 80114
P= 214657 collisions: 80521
P= 495851 collisions: 41533
P= 15485557 collisions: 2001
Kollisionen ;)
zum Vergleich: bei CPython-internen Implementierung treten 7 Kollisionen auf.

Btw:
Which hashing algorithm is best for uniqueness and speed? - Programmers Stack Exchange ist eigentlich ganz gut als "inoffizielle" Übersicht (die üblichen Verdächtigen schön zusammengefasst und auf Kollisionen/Ausführungsaufwand getestet).

Damit es nicht ganz so OT wird:
Je nach Compiler/Zielbetriebssystem wäre auch eine Bibliothek wie PolarSSL oder OpenSSL/GnuTLS eine Lösung - diese bieten neben Hashing auch Verschlüsselungsalgorithmen (und zumindest OpenSSL+PolarSSL habe ich auf einem Windows compiliert bekommen, wobei PolarSSL definitiv auch mit dem MS-VC Compiler geht)
 

CDW

Moderator
Mitarbeiter
Das ist kein Hexenwerk ;)

Beispiel "from scratch":
1. leeren Projektordner "simple_hasher" erstellen
2. einen Unterordner "sha2" drin erstellen

3. PolarSSL https://polarssl.org/download Packet herunterladen,
irgendwo entpacken (7zip, als Entpacker, kommt mit TGZ-Dateien zurecht).

4. Dokumentation öffnen:
https://polarssl.org/api/sha2_8h.html
5. die Dokumentation sich ansehen :)

6.demnach erstmal aus:
\polarssl-1.2.8\include\polarssl\
die sha2.h, config.h
und aus
\polarssl-1.2.8\library
die sha2.c
kopieren und im Projekt-Unterordner "sha2" einfügen (normalerweise gibt man stattdessen die polarssl-Verzeichnisse
beim Kompilieren als Zusatzverzeichnisse zum Includen/Linken/Codecompilieren an ;) )

Nicht vergessen, in sha2.c
PHP:
#include "polarssl/config.h"
durch
#include "config.h"
PHP:
#include "polarssl/sha2.h"
durch
#include "sha2.h"
zu ersetzen, da wir eine andere Ordnerhierarchie haben.

An dieser Stelle möchte ich (nochmal) erwähnen:
es lohnt sich auch mal mit dem "drumherum" des Programmierens (also der richtigen Konfiguration des Compilers und Linkers) zu beschäftigen - korrekte Include/Lib und Sourcenagaben sowie die einarbeitung in die üblichen Tool-Chains (make, cmake) erspart einem letzendich sehr viel Rumgetippe und Anpassungen ;)

----------------------
Eine leere "demo.c" anlegen.
Als includes und defines wird sowas reichen:
PHP:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "sha2/sha2.h"

#define HASH_LEN 32
#define USE_SHA256 0
#define TRUE 1
#define FALSE 0
Da es eine Demo sein soll, brauchen wir auch eine schöne Ausgabe für "gehashte" Passwörter:
PHP:
void show(const uint8_t *buf, size_t len)
{
  size_t i;
  for (i = 0; i < len; i++) {
      if (i % 16 == 0) putc('\n', stdout);
      printf("%02x ", buf[i]);
  }    
  putc('\n', stdout);
}
Die Doku sagt hier: https://polarssl.org/api/sha2_8h.html#ad7cba3c4768ff7acb4ad7294e87d0580
das der Aufruf so zu erfolgen hat:
PHP:
void sha2	(	const unsigned char * 	input,
size_t 	ilen,
unsigned char 	output[32],
int 	is224 
)
wir geben also Pointer auf unsere Daten, die Länge dieser Daten und einen Pointer auf ein 32-Byte Array für die Ausgabe.
Zusätzlich 0 oder 1, ob SHA224 oder SHA256 benutzt werden soll (siehe #define USE_SHA256 0 weiter oben - 'lesbare' Definition für faule)

Minimales Beispiel:
PHP:
uint8_t pass_hash[HASH_LEN];  
sha2(pass, strlen(pass), pass_hash, USE_SHA256);

oder im Kontext einer kompletten Funktion:
PHP:
int password_validation(uint8_t *pass, uint8_t *correct_hash)
{ 
  uint8_t pass_hash[HASH_LEN];
  
  sha2(pass, strlen(pass), pass_hash, USE_SHA256);
  puts("hashed input:");
  show(pass_hash, sizeof(pass_hash));
  if (memcmp(correct_hash, pass_hash, sizeof(pass_hash))) return FALSE;
  
  return TRUE;
 }
correct_hash ist dabei ein 32-byte Array mit einem Hash, der z.B aus einer Datei geladen wurde.

Da es keine Fehlermeldung gibt, ob das ganze auch funktionert,
sollten wir im Programm noch einen Selbst-Check einfügen - die Testvectoren
kann man sich hier "leihen":
https://www.cosic.esat.kuleuven.be/nessie/testvectors/hash/sha/Sha-2-256.unverified.test-vectors
PHP:
int self_check()
{
  const uint8_t test_vect_0_empty[HASH_LEN] = 
  {
    0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14,
    0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
    0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C,
    0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
  };
  const uint8_t test_vect_4_abcd[HASH_LEN] = 
  {
    0x71, 0xC4, 0x80, 0xDF, 0x93, 0xD6, 0xAE, 0x2F, 
    0x1E, 0xFA, 0xD1, 0x44, 0x7C, 0x66, 0xC9, 0x52, 
    0x5E, 0x31, 0x62, 0x18, 0xCF, 0x51, 0xFC, 0x8D, 
    0x9E, 0xD8, 0x32, 0xF2, 0xDA, 0xF1, 0x8B, 0x73
  };
  uint8_t outhash[HASH_LEN];
  uint8_t message[] = "abcdefghijklmnopqrstuvwxyz";

  sha2("", 0, outhash, USE_SHA256); /* empty message */
  if (memcmp(test_vect_0_empty, outhash, HASH_LEN) != 0) return FALSE;
  sha2(message, strlen(message), outhash, USE_SHA256);
  if (memcmp(test_vect_4_abcd, outhash, HASH_LEN) != 0) return FALSE;
  return TRUE;

}
Und eine main hinzufügen:
PHP:
int main(void)
{    
  uint8_t correct_password[] = "user's password"; 
  uint8_t* wrong_password;
  uint8_t stored_hash[HASH_LEN];
  
  if (!self_check()){
    puts("Self check failed!\n");
    return -1;
  }
  /* read a hash value from a file/database
  replace this code with your own implementation ;) */   
  sha2(correct_password, strlen(correct_password), 
       stored_hash, USE_SHA256);
  puts("correct hash value:");
  show(stored_hash, sizeof(stored_hash));    

  /* get user password.
   replace this code with your own implementation ;) */
  wrong_password = "admin";
  if (password_validation(wrong_password, stored_hash)){
    puts("Auth OK!\n");
  } else {
  puts("Wrong password!\n");
  }
 
  if (password_validation(correct_password, stored_hash)){
    puts("Yea!!!\n");
  } else {
    puts("Wrong!\n");
  }   
  
  getchar();
  return 0;
}
Zur Demonstration werden ein falsches und ein korrektes Passwort gehasht und verglichen (das Einlesen der Passwörter als Benutzereingabe sowie das Einlesen des Hashs aus einer Datei musst Du selbst umsetzen)

Kompilieren kann man das Ganze schon in der Kommandozeile:
GCC
PHP:
D:\xyz\simple_sha2>gcc -O2 -std=c99 sha2/sha2.c demo.c

falls man MS Visual C++ benutzt, gibt es die nette "Visual Studio Eingabeaufforderung"
(eingentlich nix anderes eine Batch, die alle nötigen Umgebungsvariablen hinzufügt)
a) entweder startet man diese Eingabeaufforderung - und wechselt dann zum Projektordner
b) oder man sucht eine vcvarsall.bat im VS Installationsordner und führt diese in der Konsole aus,
bevor man in dieser Konsole zum Projektordner wechselt und irgendwas kompiliert:
Code:
D:\Users\CDW>"d:\VS\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
cd D:\projektbla

D:\xyz\simple_sha2>cl /arch:SSE /O2 /GL /MT /nologo /TC sha2/sha2.c demo.c
PHP:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "sha2/sha2.h"

#define HASH_LEN 32
#define USE_SHA256 0
#define TRUE 1
#define FALSE 0

void show(const uint8_t *buf, size_t len)
{
  size_t i;
  for (i = 0; i < len; i++) {
      if (i % 16 == 0) putc('\n', stdout);
      printf("%02x ", buf[i]);
  }    
  putc('\n', stdout);
}

int self_check()
{
  const uint8_t test_vect_0_empty[HASH_LEN] = 
  {
    0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14,
    0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
    0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C,
    0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
  };
  const uint8_t test_vect_4_abcd[HASH_LEN] = 
  {
    0x71, 0xC4, 0x80, 0xDF, 0x93, 0xD6, 0xAE, 0x2F, 
    0x1E, 0xFA, 0xD1, 0x44, 0x7C, 0x66, 0xC9, 0x52, 
    0x5E, 0x31, 0x62, 0x18, 0xCF, 0x51, 0xFC, 0x8D, 
    0x9E, 0xD8, 0x32, 0xF2, 0xDA, 0xF1, 0x8B, 0x73
  };
  uint8_t outhash[HASH_LEN];
  uint8_t message[] = "abcdefghijklmnopqrstuvwxyz";

  sha2("", 0, outhash, USE_SHA256); /* empty message */
  if (memcmp(test_vect_0_empty, outhash, HASH_LEN) != 0) return FALSE;
  sha2(message, strlen(message), outhash, USE_SHA256);
  if (memcmp(test_vect_4_abcd, outhash, HASH_LEN) != 0) return FALSE;
  return TRUE;

}

int password_validation(uint8_t *pass, uint8_t *correct_hash)
{ 
  uint8_t pass_hash[HASH_LEN];
  
  sha2(pass, strlen(pass), pass_hash, USE_SHA256);
  puts("hashed input:");
  show(pass_hash, sizeof(pass_hash));
  if (memcmp(correct_hash, pass_hash, sizeof(pass_hash))) return FALSE;
  
  return TRUE;
 }

int main(void)
{    
  uint8_t correct_password[] = "user's password"; 
  uint8_t* wrong_password;
  uint8_t stored_hash[HASH_LEN];
  
  if (!self_check()){
    puts("Self check failed!\n");
    return -1;
  }
  /* read a hash value from a file/database
  replace this code with your own implementation ;) */   
  sha2(correct_password, strlen(correct_password), 
       stored_hash, USE_SHA256);
  puts("correct hash value:");
  show(stored_hash, sizeof(stored_hash));    

  /* get user password.
   replace this code with your own implementation ;) */
  wrong_password = "admin";
  if (password_validation(wrong_password, stored_hash)){
    puts("Auth OK!\n");
  } else {
  puts("Wrong password!\n");
  }
 
  if (password_validation(correct_password, stored_hash)){
    puts("Yea!!!\n");
  } else {
    puts("Wrong!\n");
  }   
  
  getchar();
  return 0;
}

Das war's schon ;)


Wobei PolarSSL auch schon fertige PBKDF2 PBKDF2 sowie Verschlüsselungen bietet - diese sind nicht schwerer einzubinden, als SHA2 im Beispiel oben. Man sollte dann natürlich nicht "Umkopieren", sondern die Daten da belassen, wo sie sind - polarssl lässt sich entweder zu einer Bibliothek kompilieren, so dass man nur die jeweiligen Header sowie die erzeugte LIB Datei braucht oder man kann die verwendeten Verfahren im Projekt als "Externe Sourcen" mitcompilieren lassen.
Alles nur eine Frage der nötigen Konfiguration für die Entwicklungsumgebung oder der Parameter für den Compiler - sofern man irgendwas "sinnvolles" programmieren möchte, kommt man sowieso nicht drumherum, da man sonst zuviele Räder neuerfinden müsste ;)

PS: das ganze ist "fast C99" - damit die Compilierung mit Visual C++ im C-Modus ablaufen kann (ansonsten müsste man hässliche CPP Kompatibilitätscasts einfügen :rolleyes: )
 
Zuletzt bearbeitet:
Oben