SHA1 Hash bzw. Salt



  • @zero01 sagte in SHA1 Hash bzw. Salt:

    Formatier´ deinen Code bitte vernünftig, 8 Zeichen Einrückung sind fürchterlich. Und mehrere aufeinanderfolgende Leerzeilen auch.
    Du übergibst deine Parameter jetzt per value statt per reference. Das war sicher auch nicht der Plan...
    Und was deine Frage nach den Aufrufparametern für die WINAPI angeht: Was gibt &password denn zurück? Die Adresse des Objekts, das den Text speichert, oder einen Zeiger auf den Text selbst?



  • Hallo Doc,
    sorry für die Formatierung. Die Parameter per Value habe ich umgestellt, da die Rückgabe nun per return realisiert ist und ich sie im nachgang, wie bereits angemerkt, noch const machen kann.

    &password Gibt die Adresse des Objekts selbst zurück, da explizit der Referenzierungsoperator davor steht. Der Pointer auf den Text selbst (value) wäre hier schlicht password bzw. password.c_str() Siehe da, die Ausgabe geht nach Umstellung der folgenden Funktion schon mal trotz zusätzlichem Zeichenwirwar in Richtung hex:

    CryptHashData(handle_hash, password.c_str(), password.length, 0);
    

    Zugegebenermaßen steige ich bei den Casts von Buff vollständig aus. Sind hier die Casts überhaupt vonnöten? ich vermute nein aber bin mir absolut nicht sicher. Evtl. liegt der Fehler auch noch an der Längenermittlung des std::string password; password.length();

    Ich bin jetzt bis kommenden Donnerstag im Aussendienst und werde erst nach meiner Rückkehr weiter machen können.



  • Schalt mal die compiler warnungen an.

    CryptHashData(handle_hash, password.c_str(), password.length, 0);
    

    Da ist ein fehler im 3. Parameter 😉



  • Nach dem jetzigen, dank eurer Hilfe, erlangten Verständnis sieht mein Lösungsversuch jetzt wie folgt aus. Allerdings habe ich noch Zeichenwirrwar im hex string. Ist es richtig, dass die Übergabe via &Buff[0] erfolgen muss, da deine Funktion einen char Pointer erwartet und kein Array of char? Ich gebe deiner Funktion ja so die erste Stelle des Arrays via Reference und mit BuffSize die Länge.

    Kompilieren tut er es klaglos aber es kommt immer noch Müll herraus.

    std::string SHA1_Class::GetSHA1asString(std::string password, std::string salt)
    {
    
    	  char Buff[256];
    	  unsigned long BuffSize;
    
    	  HCRYPTPROV handle_cryptprov = 0;
    	  HCRYPTHASH handle_hash = 0;
    
    
    
    	   if(CryptAcquireContext(&handle_cryptprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
    	  {
    
    
    				if(CryptCreateHash(handle_cryptprov, CALG_SHA1, 0, 0, &handle_hash))
    			   {
    
    
    						  if(CryptHashData(handle_hash, password.c_str(), password.length(), 0))
    						  {
    
    								   ZeroMemory(&Buff, sizeof(Buff));
    								   BuffSize = sizeof(Buff);
    
    
    								   if(CryptGetHashParam(handle_hash, HP_HASHVAL, Buff, &BuffSize, 0))
    								   {
    
    										 //---Ressourcen freigeben
    										 CryptDestroyHash(handle_hash);
    										 CryptReleaseContext(handle_cryptprov, 0);
    
    
    										 return buffer_to_hex_string(&Buff[0], BuffSize);
    
    								   }
    								   else
    								   PrintErrorToScreen(GetLastError());
    						  }
    						  else
    						  PrintErrorToScreen(GetLastError());
    			   }
    			   else
    			   PrintErrorToScreen(GetLastError());
    	  }
    	  else
    	  PrintErrorToScreen(GetLastError());
    
    
    
    
    
    	  //---Ressourcen freigeben
    	  if(handle_hash != 0)
    	  CryptDestroyHash(handle_hash);
    
    	  if(handle_cryptprov != 0)
    	  CryptReleaseContext(handle_cryptprov, 0);
    
    
    }
    


  • @firefly meinst du weil er unsigned long erwartet und ich ihm unsigned int liefere? Oder müsste ich gar +1 rechnen da der c_str() nullterminiert ist?

    Ich muss jetzt leider los, bis nächste Woche....



  • Nein meine ich nicht.

    Was ist der unterschied zwischen

    password.length
    

    und

    password.length()
    


  • @zero01 sagte in SHA1 Hash bzw. Salt:

    sorry für die Formatierung.

    Und warum änderst du sie dann nicht? Du rückst immer noch mit 8 Zeichen ein und bist äußerst großzügig mit Leerzeilen. Es macht das Lesen anstrengend, wenn man schon für 3 Funktionsaufrufe scrollen muss. Bitte formatier´ den Quelltext so, dass man ihn hier im Forum vernünftig lesen kann.

    @zero01 sagte in SHA1 Hash bzw. Salt:

    Die Parameter per Value habe ich umgestellt, da die Rückgabe nun per return realisiert ist und ich sie im nachgang, wie bereits angemerkt, noch const machen kann.

    Wo? Ich seh da keine Übergabe per const-reference.



  • Auf dem Smartphone ist´s jetzt noch schlimmer, ich hatte eingerückt aber beim Kopieren ist mir die Formatierung wieder flöten gegangen, ich achte das nächste mal genau drauf.

    Wie gesagt, kann ich es gerne als const reference übergeben. Oder besser sogar als unsigned const ref? Ist diese Vorgehensweiße sicherheitsrelevant? Ich stehe gerade etwas auf dem Schlauch was daran schlimm ist ein Value für den ersten erfolgreichen Test einfach so zu übergeben.

    @firefly Kurz vor Verlassen des Büros habe ich alle Compiler warnings aktiviert und er meckerte eine Vermischung der char typen an. Der Aufruf password.length ohne Klammern macht er nicht, daher verstehe ich nicht ganz deine Frage. Der "." ist doch eine referenzierter Aufruf eines members und die runden Klammern besagen, dass es sich um einen Funktionsaufruf handelt (ggf. mit returnvalue) und ohne Klammern eine Member Variable gemeint sein muss.



  • Nö, Password.length() ist ein Methodenaufruf, es gibt keine std::string::length Klasse. Du rufst die Methode length() auf dem Objekt Password auf, das hat nix mit Konstruktoren zu tun.
    Und was die Übergabe von Parametern angeht hatten wir vor kurzem einen Thread hier im Forum. Als Daumenregeln hilft dir das vllt weiter, die Punkte sind nach Priorität aufgelistet:

    1. übergib ihn als Referenz, wenn er in der Funktion beschrieben wird und vom Aufrufer benutzt wird (call by reference)
    bool decodate_date( std::time_t timestamp, unsigned short& year, unsigned short& month, unsigned short& day )
    {
       year =...
       month = ...
       day = ...
    
    1. übergib Datentypen, die in ein Register passen (aktuell fast immer 64bit) , als Kopie (call by value). Dazu gehören insbesondere all built-in Typen (bool, char, int, float, double, etc).
    double mul_div( double factor1, double factor2, double divisor )
    {
       return (factor1 * factor 2) / divisor;
    }
    
    1. übergib Datentypen, die nicht in ein Register passen und nur lesend benutzt werden, per const-Referenez (call by const reference)
    std::string calculate_sha1_hash( const std::string& input_data )
    {
       ...
    }
    


  • Super Doc! habe vielen herzlichen Dank. Ich melde mich bald

    Du hast wohl auf meinen ersten Gedanken geantwortet, den ich kurz drauf wegeditiert hatte 🙂

    Gibt mir der Aufruf der Memberfunktion Length() nicht die korrekte Länge zurück?



  • @zero01
    Genau das tut er.



  • Hallo Doc,
    folgenden Stand habe ich jetzt mit allen Tips hinbekommen. Ich vermute, dass der noch ausgegebene Datenschrott mit meinem Verständnis des gezeigten char Buff[] zusammen hängt. Mir fällt es gerade wahnsinnig schwer, ob auch die Größenermittlung mit sizeof logisch so richtig ist.

    Worin liegt eigentlich der Unterschied zwischen char Buff und char Buff[256]? Kann die Variable Buff ohne Feldlängenangabe nur ein Zeichen aufnehmen?

    std::string SHA1_Class::GetSHA1asString(const std::string &password)
    {
    
      unsigned char Buff[256];
      unsigned long BuffSize;
    
      HCRYPTPROV handle_cryptprov = 0;
      HCRYPTHASH handle_hash = 0;
    
    
      ZeroMemory(&Buff, sizeof(Buff));
      BuffSize = sizeof(Buff);
    
    
       if(CryptAcquireContext(&handle_cryptprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
      {
    	if(CryptCreateHash(handle_cryptprov, CALG_SHA1, 0, 0, &handle_hash))
    	{
    	  if(CryptHashData(handle_hash, password.c_str(), password.length(), 0))
    	  {
    		if(CryptGetHashParam(handle_hash, HP_HASHVAL, Buff, &BuffSize, 0))
    		{
    
    		   //---Ressourcen freigeben
    		   CryptDestroyHash(handle_hash);
    		   CryptReleaseContext(handle_cryptprov, 0);
    
    
    		   return buffer_to_hex_string(Buff, BuffSize);
    
    		}
    		else
    		PrintErrorToScreen(GetLastError());
    	  }
    	  else
    	  PrintErrorToScreen(GetLastError());
    	}
    	else
    	PrintErrorToScreen(GetLastError());
      }
      else
      PrintErrorToScreen(GetLastError());
    
    
    
    
    
      //---Ressourcen freigeben
      if(handle_hash != 0)
      CryptDestroyHash(handle_hash);
    
      if(handle_cryptprov != 0)
      CryptReleaseContext(handle_cryptprov, 0);
    
    
      return "0";
    
    
    }
    //------------------------------------------------------------------------------
    char SHA1_Class::nibble_to_hex( char value )
    {
    	 if( value > 9 )
    	 return 'a' + value - 10;
    	 else
    	 return '0' + value;
    }
    //------------------------------------------------------------------------------
    std::string SHA1_Class::buffer_to_hex_string( const char* buffer, unsigned long size )
    {
    	std::string returnvalue;
    
    	returnvalue.resize( size * 2 );
    
    	for( unsigned long i = 0; i < size;  i++ )
    	{
    	  returnvalue[2 * i    ] = nibble_to_hex( buffer[i] >> 4 );
    	  returnvalue[2 * i + 1] = nibble_to_hex( buffer[i] & 0x0f );
        }
    
    	return returnvalue;
    }
    


  • Ist das Thema noch aktuell?



  • Hi Doc,
    das Thema ist noch aktuell. Leider komme ich aufgrund anderer Projekte momentan zu nichts. Ich habe mir auch weiter Gedanken zu dem Thema gemacht, die ich noch weiter in den Quelltext einbauen möchte. Ist der Umgang mit dem im letzten Stand gezeigten char Array der richtige Weg?


Anmelden zum Antworten