#include #include #include #include #include #include "Base64Encode.h" #include "Base64Decode.h" int nextPassword(int charlistLength, const char* charlist, int passwordLength, int* passwordIndex, char* password) { if(passwordLength > 1) { if(nextPassword(charlistLength, charlist, passwordLength - 1, passwordIndex + 1, password + 1) > 0) { return 1; } } (*passwordIndex)++; if(*passwordIndex >= charlistLength) { *passwordIndex = 0; *password = *charlist; return 0; } *password = charlist[*passwordIndex]; return 1; } void status(int c, char* password) { time_t t; time(&t); struct tm *d = localtime(&t); printf("\r%d @ %04d-%02d-%02d %02d:%02d:%02d with ", c, d->tm_year+1900, d->tm_mon+1, d->tm_mday, d->tm_hour, d->tm_min, d->tm_sec); putchar('"'); while(*password) { // Simple UTF-16 part -> UTF-8 if(*password > 0x80 || *password < 0) { putchar(0xc3); putchar(*password - 0x40); } else { putchar(*password); } password++; } putchar('"'); putchar('\n'); } int main() { // start of config const int charlistLength = 77; char charlist[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.,______!$%#=@"; charlist[65] = 0xe5; // å in UTF-16 is [0x00, 0xe5], but we only use the lower part. charlist[66] = 0xe4; // ä charlist[67] = 0xf6; // ö charlist[68] = 0xc5; // Å charlist[69] = 0xc4; // Ä charlist[70] = 0xd6; // Ö const int saltLength = 16; const char* saltB64 = "PBEN2sa8NDIpdtvhjLYtjQ=="; const char* goal = "lbU0e7K9mQ54tlh+rZVF8YkCrOX0/d2frkuhBJUUmgtvJG0HEyPQXC+Q/X74HYwNF32gHCUbZmdXNmFwX+Y2yA=="; int passwordLength = 1; int maxPasswordLength = 30; int skip = 62900-1; // end of config setvbuf(stdout, NULL, _IONBF, 0); int passwordIndex[maxPasswordLength]; char password[maxPasswordLength + 1]; int c = 0; for(;passwordLength <= maxPasswordLength; passwordLength++) { for(int i = 0; i < passwordLength; i++) { passwordIndex[i] = 0; password[i] = charlist[0]; } passwordIndex[passwordLength - 1] = -1; password[passwordLength] = 0; char* salt; Base64Decode(saltB64, &salt); unsigned char initData[saltLength + passwordLength*2 + 1]; unsigned char* data = initData; unsigned char* passwordStart = initData + saltLength; memcpy(initData, salt, saltLength); while(nextPassword(charlistLength, charlist, passwordLength, passwordIndex, password)) { if(skip >= 0) { if(skip-- > 0) { c++; continue; } status(c + 1, password); } for(int i = 0; i < passwordLength; i++) { passwordStart[i*2] = password[i]; passwordStart[i*2 + 1] = 0; } data = initData; unsigned char hashData1[SHA512_DIGEST_LENGTH + 4]; unsigned char hashData2[SHA512_DIGEST_LENGTH + 4]; unsigned char* hash = hashData1; unsigned char* loopIndex;// = data + SHA512_DIGEST_LENGTH; SHA512(data, saltLength + passwordLength*2, hash); for(int i = 0; i < 100000; i++) { if(i & 1) { hash = hashData1; data = hashData2; } else { hash = hashData2; data = hashData1; } loopIndex = data + SHA512_DIGEST_LENGTH; loopIndex[0] = (i >> 0) & 0xff; loopIndex[1] = (i >> 8) & 0xff; loopIndex[2] = (i >> 16) & 0xff; loopIndex[3] = (i >> 24) & 0xff; SHA512(data, SHA512_DIGEST_LENGTH + 4, hash); } const char* hash2 = (const char*) hash; char* b64; Base64Encode(hash2, &b64, SHA512_DIGEST_LENGTH); putchar('.'); if(++c % 100 == 0) { status(c, password); } if(strcmp(b64, goal) == 0) { printf("\n%d @ '%s' => '%s'\n", c, password, b64); return 0; } } } return 1; }