[Crypto API CryptEncrypt] 2 gleiche Str, unterschiedlicher Ciphertext



  • Hi Leute,

    ich versuche gerade 2 String mit den gleichen Inhalt zu verschluesseln aber leider ist der Ciphertextein unterschiedlicher.

    Mein vorgehen:

    /* .... */
    CryptAcquireContext(&m_hCryptProvider, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
    /* .... */
    CryptGenKey( m_hCryptProvider, CALG_RSA_KEYX, RSA1024BIT_KEY | CRYPT_EXPORTABLE, &m_hKey)
    /* .... */
    std::string text("test txt");
    std::string encOne(text);
    std::string encTwo(text);
    /* das naechste fuer encOne und encTwo aufrufen */
    CryptEncrypt( m_keyManager->getKeyHandle() , NULL, TRUE, 0,
    		(BYTE*) &data[0], &dataSize, data.size() ) )
    
    /* jetz encOne und encTwo als hex values ausgeben */
    

    Beispiel Ausgabe:

    one:
    +-----------------------+
    3c4791f7 feba10ed b7ba3c43 2b6df39a 265094f1 b2d7a1e2
    db2ebfee e32aba84 d1a0d97f 0ece49a1 a73839e1 a4a0f191
    7f03be6c 726bf511 e2f45702 5a86666d 95ce10c4 e78a3a72
    69c91003 1723820a 1725372f ff43a8dc 1e9c7d2a 9b20a19d
    13f28031 c951a40c 6adcb836 3e0eacaf 8b6a9e20 fbe828ab
    a367995a 32161f9a
    +-----------------------+
    two:
    +-----------------------+
    321def22 ca1ffa78 321a717e 9971ba9b bea0f8dd c60b29ae
    4642301f a976bfdb 83c81fa4 6877ed4f e78ac452 397e68fa
    cd4e9230 36285aa5 096f4c6c f7c1ac0a f109d1eb 44e43c4c
    96730244 e23da614 f9cd3225 256976d1 12d798e1 cde89e70
    c2d8c251 6e2a14a3 ab118b95 61db0f91 a865e41b 7b078768
    d329e885 4abe1899
    +-----------------------+

    Sollte doch der gleiche Inhalt sein oder steh ich jetzt total auf dem Schlauch?
    Oder muss ich den Key/Context manuel reseten?

    Gruessle

    PS: falls ihr noch mehr Code brauch einfach bescheid geben

    €: boese Rechtschreibung



  • Irgendwie enthält Dein Code nicht die wichtigen Teile...

    Du musst beide Strings natürlich immer von 0-an verschlüsseln... Also alles neu initialisieren und dann den anderen Text auch nochmals verschlüsseln... ansonsten gibt das ein Stream, wobei die Verschlüsselung von den vorherigen Daten abhängt... deswegen gibt es dann unterschiedliche Bytes...



  • Jochen Kalmbach schrieb:

    Irgendwie enthält Dein Code nicht die wichtigen Teile...

    Du musst beide Strings natürlich immer von 0-an verschlüsseln... Also alles neu initialisieren und dann den anderen Text auch nochmals verschlüsseln... ansonsten gibt das ein Stream, wobei die Verschlüsselung von den vorherigen Daten abhängt... deswegen gibt es dann unterschiedliche Bytes...

    Warum was fehlt den?

    Was heisst alles neu zu initialisieren? Context und Key oder nur Key|Context?

    Meine Annahme war, dass der "Final" Parameter bei CryptEncrypt angibt wenn ein Stream fertig ist, dann der Algorithmus noch Sachen erledigen kann den auf den letzten Block angewant werden muessen und der Schluessle danach wieder auf den Ausgangszustand zurueckgesetzt wird und ich mit dem gleichen Schluessel was neues verschluesseln kann.

    Ich bin jetzt auch von der Crypto API auf CryptoPP umgestiegen da ich das vorher schon einmal benutzt habe. Wollte aber halt die Crypto API benutzten da mein Programm nur auf Windows laufen soll und ich somit was an der groesse einsparen koennte.

    Waere aber trotzdem gut zu wissen wo mein Denkfehler liegt.

    Gruessle



  • Der Code mit dem "data" Teil fehlt...



  • Jochen Kalmbach schrieb:

    Der Code mit dem "data" Teil fehlt...

    Oh sorry:

    mit:

    std::string text("test txt");
    std::string encOne(text);
    std::string encTwo(text);
    /* das naechste fuer encOne und encTwo aufrufen */
    CryptEncrypt( m_keyManager->getKeyHandle() , NULL, TRUE, 0,
            (BYTE*) &data[0], &dataSize, data.size() ) )
    

    meine ich:

    std::string text("test txt");
    std::string encOne(text);
    std::string encTwo(text);
    
    DWORD dataSize /* = encOne size + auf die block size aufgerundet */
    CryptEncrypt( m_hKey , NULL, TRUE, 0,
            (BYTE*) &encOne[0], &dataSize, encOne.size() ) )
    
    dataSize /* = encTwo size + auf die block size aufgerundet */
    CryptEncrypt( m_hKey , NULL, TRUE, 0,
            (BYTE*) &encTwo[0], &dataSize, encTwo.size() ) )
    


  • ok hier noch schnell ein kompilierbares Beispiel:

    #include <iostream>
    #include <string>
    #include <sstream>
    #include <Windows.h>
    #include <WinCrypt.h>
    
    #include <iomanip>
    
    std::string toHex(const std::string data, unsigned space = 4, unsigned newLine = 24) {
    
    	std::stringstream ss;
    	for( unsigned i = 0 ; i < data.size(); i++ ) {
    		unsigned char c = data[i];
    		ss << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) c;
    		if( i+1 != 1) {
    			if( ((i+1) % newLine) == 0 )
    				ss << "\n";
    			else if( ((i+1) % space) == 0)
    				ss << " ";
    
    		}
    	}
    
    	return ss.str();
    }
    
    int main(int argc, char** argv) 
    {
    
    	std::string text("textasdfasdf");
    	std::string encOne( text );
    	std::string encTwo( text);
    	DWORD size = text.size();
    
    	encOne.resize( 128 );
    	encTwo.resize( 128);
    
    	HCRYPTPROV hProvider = 0;
    	HCRYPTKEY hKey = 0;
    
    	CryptAcquireContext(&hProvider, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    	CryptGenKey( hProvider, CALG_RSA_KEYX, RSA1024BIT_KEY | CRYPT_EXPORTABLE, &hKey);
    
    	CryptEncrypt( hKey, NULL, TRUE, 0, (BYTE*) &encOne[0], &size, 128 );
    
    	size = text.size();
    	CryptEncrypt( hKey, NULL, TRUE, 0, (BYTE*) &encTwo[0], &size, 128 );
    
    	std::cout << "one: \n" << toHex(encOne ) << "\n\n";
    	std::cout << "two: \n" << toHex(encTwo);
    	return 0;
    }
    

    Ausgabe:

    one:
    7558256a a123664a ebf4ca73 a2990ba9 a64d13b9 dbb9c90a
    df588d4f e1647c8d a40a575c 8320b534 c9d103c2 85354ce4
    c21a7132 e538de2b becdfe4b 51050486 560ed511 1c79f082
    a10c74d4 763d02bd db726956 f7d4b46a ffb86c1c 8d84cea4
    5132e157 b93ea742 cf22ed2e 853fc12c f241f8a5 be526f47
    c275562a bf319376

    two:
    e016ea61 2298dd70 9724a29a 2fcbd1ec 41ff7812 06f24d03
    ea22a2ec 1def0f97 450aa3a7 68bdb9a8 300858fe 942e9bb2
    29b45c13 eaea0849 37566218 65aba84c 588129ef 959251fb
    bb1ef28e 0a0fc848 ba251521 205d5c34 afe60e5a a8124a68
    c2604165 480a8aa7 faa46e2a 1237cf0f 82bee740 8880e7b4
    55cdae35 8e2ff782



  • Deine Verwendung von std::string ist nicht wirklich Standardkonmform. Zumindest nicht nach C++ 03.
    Kopier die Strings lieber in einen std::vector<char> .



  • hustbaer schrieb:

    Deine Verwendung von std::string ist nicht wirklich Standardkonmform. Zumindest nicht nach C++ 03.
    Kopier die Strings lieber in einen std::vector<char> .

    Hmm ok. Bin ich richtig der Annahme das bei ein std::string die Daten intern nicht unbedingt an einem Stueck gespeichert werden muessen und bei einem Vector<char> schon?

    Oder was ist der Grund?


Anmelden zum Antworten