003
24.01.2005, 18:17 Uhr
FloSoft
Medialer Over-Flow (Administrator)
|
md5 kannste z.b mit folgender Klasse machen, hab ich geschrieben ;P
md5.cpp
C++: |
///////////////////////////////////////////////////////////////////////////////////////// // MD5.cpp // ///////////////////////////////////////////////////////////////////////////////////////// #include <stdio.h> #include <memory.h>
#include "md5.h"
CMD5::CMD5(void) { Init(); }
CMD5::~CMD5(void) { }
void CMD5::Init(void) { m_cFertig = 0; // noch kein Schlüssel generiert
memset(m_ui4Count,0,sizeof(m_ui4Count)); // Zähler auf 0 setzen
// RunTime-Start-Konstanten setzen m_ui4State[0] = 0x67452301; m_ui4State[1] = 0xefcdab89; m_ui4State[2] = 0x98badcfe; m_ui4State[3] = 0x10325476; }
uchar* CMD5::GetHexKey(uchar *key, uint4 len) { if(m_cFertig == 0) // kein generierter MD5, Abbruch! return NULL;
// Bufferfehler abfangen if(!key || len < 33) return NULL;
// 32-Zeichen CMD5 aus Rohdaten generieren for (uchar i = 0; i < 16; i++) { sprintf((char*)key+i*2, "%02x", m_cMD5Key[i]); }
return key; }
uchar CMD5::SetSource(uchar *input, uint4 len) { if(m_cFertig == 1) // schon generierter MD5, Abbruch! return 0;
uint4 ui4InputIndex, ui4PufferIndex; uint4 ui4PufferPlatz;
ui4PufferIndex = (unsigned int)((m_ui4Count[0] >> 3) & 0x3F);
if ( (m_ui4Count[0] += ((uint4) len << 3))<((uint4) len << 3) ) m_ui4Count[1]++; m_ui4Count[1] += ((uint4)len >> 29);
ui4PufferPlatz = 64 - ui4PufferIndex; // wieviel brauchen wir noch?
if (len >= ui4PufferPlatz) // ist unser Puffer zu klein? { // ok erstmal soviel reinfüllen wie reingeht memcpy (m_cBuffer + ui4PufferIndex, input, ui4PufferPlatz); // nun umwandeln Umwandeln(m_cBuffer);
// ok nun ohne Buffer den Rest for (ui4InputIndex = ui4PufferPlatz; ui4InputIndex + 63 < len; ui4InputIndex += 64) Umwandeln(input+ui4InputIndex);
ui4PufferIndex = 0; // ok Rest wieder in den Puffer } else ui4InputIndex = 0; // ok unser Puffer ist groß genug, alles passt rein
// ok und nun rein damit memcpy(m_cBuffer + ui4PufferIndex, input + ui4InputIndex, len - ui4InputIndex);
return 1; // also ok }
// nun etwas magie :P void CMD5::Umwandeln(uchar block[64]) { if(m_cFertig == 1) // schon generierter MD5, Abbruch! return;
uint4 a = m_ui4State[0], b = m_ui4State[1], c = m_ui4State[2], d = m_ui4State[3], x[16];
UChar2UInt4(x, block, 64); // unseren Block in Integer umwandeln
/* Runde 1 */ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Runde 2 */ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Runde 3 */ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Runde 4 */ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
m_ui4State[0] += a; m_ui4State[1] += b; m_ui4State[2] += c; m_ui4State[3] += d;
// unseren mini-Buffer wieder leeren memset( x, 0, sizeof(x)); }
void CMD5::UChar2UInt4(uint4 *output, uchar *input, uint4 len) { uint4 i, j;
for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); }
void CMD5::UInt42UChar(uchar *output, uint4 *input, uint4 len) { uint4 i, j;
for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (uchar) (input[i] & 0xff); output[j+1] = (uchar) ((input[i] >> 8) & 0xff); output[j+2] = (uchar) ((input[i] >> 16) & 0xff); output[j+3] = (uchar) ((input[i] >> 24) & 0xff); } }
void CMD5::Generieren() { if(m_cFertig == 1) // schon generierter MD5, Abbruch! return;
uchar bits[8]; uint4 index, padLen;
// unseren leerblock (falls nötig) definieren und initialisieren // 0x80 == 1000 0000 (1-Bit ne 1, dann restliche Bits 0) static uchar PADDING[64]={ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// Anzahl unserer Bits speichern UInt42UChar (bits, m_ui4Count, 8);
// Blocks vervollständigen index = (uint4) ((m_ui4Count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); SetSource(PADDING, padLen);
// ok Länge der Originalnachricht anhängen SetSource(bits, 8);
// OK nun unseren Schlüssel von Integern wieder in chars umwandeln UInt42UChar (m_cMD5Key, m_ui4State, 16);
// ok Puffer wieder leeren memset (m_cBuffer, 0, sizeof(m_cBuffer));
m_cFertig = 1; // so endlich fertig }
////////////////////////////////////////////////////////////// // nun unsere Transformierroutinen für die einzelnen Runden //
inline unsigned int CMD5::linksrotation(uint4 x, uint4 n) { return (x << n) | (x >> (32-n)); }
// unsere F, G, H und I Funktionen
inline unsigned int CMD5::F(uint4 X, uint4 Y, uint4 Z) { return (X & Y) | (~X & Z); }
inline unsigned int CMD5::G(uint4 X, uint4 Y, uint4 Z) { return (X & Z) | (Y & ~Z); }
inline unsigned int CMD5::H(uint4 X, uint4 Y, uint4 Z) { return X ^ Y ^ Z; }
inline unsigned int CMD5::I(uint4 X, uint4 Y, uint4 Z) { return Y ^ (X | ~Z); }
// Nach Beispielen (und auch ausprobierten Versuchen, die Transformation // und die Additionen/Verschiebungen in eine Funktion zu packen) habe ich nun // auch eigene Funktionen für dieses gebaut inline void CMD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += F(b, c, d) + x + ac; a = linksrotation(a, s) + b; }
inline void CMD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += G(b, c, d) + x + ac; a = linksrotation(a, s) + b; }
inline void CMD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += H(b, c, d) + x + ac; a = linksrotation(a, s) + b; }
inline void CMD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += I(b, c, d) + x + ac; a = linksrotation(a, s) + b; }
|
md5.h
C++: |
///////////////////////////////////////////////////////////////////////////////////////// // md5.h // ///////////////////////////////////////////////////////////////////////////////////////// #ifndef MD5_H_INCLUDED #define MD5_H_INCLUDED
#ifdef _WIN32 #pragma once #endif
typedef unsigned long uint8; // 64-Bit Integer, 0 - 18.446.744.073.709.551.615 typedef unsigned int uint4; // 32-Bit Integer, 0 - 4.294.967.295 typedef unsigned short int uint2; // 16-Bit Integer, 0 - 65.535 typedef unsigned char uchar; // 8-Bit Integer, 0 - 255
// Umwandelkonstanten #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21
class CMD5 { public: CMD5(void); virtual ~CMD5(void); uchar *GetHexKey(uchar *key, uint4 len); // liefert uns den 32+1-Zeichen MD5-Schlüssel uchar SetSource(uchar *input, uint4 len); // setzt die Quelldaten void Generieren(); // generiert uns den Roh-Schlüssel
private: void Init(void); // Initialisierung void Umwandeln(uchar block[64]); // unsere eigentliche MD5-Routine static void UChar2UInt4(uint4 *output, uchar *input, uint4 len); // wandelt uns charinput in richtigen integer um static void UInt42UChar(uchar *output, uint4 *input, uint4 len); // wandelt uns integerinput in chars um
static inline uint4 linksrotation (uint4 x, uint4 n); static inline uint4 F (uint4 x, uint4 y, uint4 z); static inline uint4 G (uint4 x, uint4 y, uint4 z); static inline uint4 H (uint4 x, uint4 y, uint4 z); static inline uint4 I (uint4 x, uint4 y, uint4 z); static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
private: uint4 m_ui4State[4]; // Runtime-Daten uint4 m_ui4Count[2]; // menge unserer "bits", benötigt für Auffüllen der Blöcke, usw uchar m_cBuffer[64]; // unser Inputbuffer uchar m_cMD5Key[16]; // unser (roher) MD5-Schlüssel uchar m_cFertig; };
#endif // MD5_H_INCLUDED
|
Aufrufen dann folgendermaßen:
C++: |
CMD5 mymd5; char source[] = "Dies ist ein Eingabetext"; char md5[33];
mymd5.SetSource((unsigned char*)source,(unsigned int)strlen(source)); mymd5.Generieren();
if(mymd5.GetHexKey((unsigned char*)md5,(unsigned int)33) == 0) { std::cerr << "RUNTIME ERROR: GetHexKey lieferte 0" << std::endl; }
|
-- class God : public ChuckNorris { }; |