#include #include #include #include #include #include #include "stringutils.h" #include "args.h" // 0x300, "A04EF996651696" // 0x370, "A04EF996651696" // 0x160, "A04EF996651696" // 0x060, "A04EF996651696" // 0x1003, "A04EF996651696" // 0x20555, "7E8973DDB411D16301CAD67409F" // 0x20225, "7E8973DDB411D16301CAD67409F" // 0x201, "7E8973DDB411D16301CAD67409F" // 0x196, "7E8973DDB411D16301CAD67409F" // cl -Zi -nologo -EHsc -Wall -wd4826 -wd4571 -wd4710 -wd4668 -wd4820 dervkey.cpp advapi32.lib // typedef std::vector ByteVector; struct win32_error { win32_error(const char*api) : _api(api), _err(GetLastError()) { } ~win32_error() { printf("ERROR %08x in %s\n", _err, _api); } DWORD _err; const char*_api; }; class cryptapi { HCRYPTPROV _hProv; class cryptkey { HCRYPTKEY _h; public: cryptkey(HCRYPTKEY h) : _h(h) { } cryptkey() : _h(0) { } ~cryptkey() { if (_h && !CryptDestroyKey(_h)) throw win32_error("CryptDestroyKey"); } operator HCRYPTKEY() const { return _h; } HCRYPTKEY* operator&() { return &_h; } DWORD getdwparam(DWORD type) { DWORD dw; DWORD size= sizeof(dw); if (!CryptGetKeyParam(_h, type, (BYTE*)&dw, &size, 0)) throw win32_error("CryptGetKeyParam"); return dw; } }; class crypthash { HCRYPTHASH _h; public: crypthash() : _h(0) { } crypthash(HCRYPTHASH h) : _h(h) { } ~crypthash() { if (_h && !CryptDestroyHash(_h)) throw win32_error("CryptDestroyHash"); } operator HCRYPTHASH() const { return _h; } HCRYPTHASH* operator& () { return &_h; } }; public: cryptapi() { if (CryptAcquireContext(&_hProv, _T("UN"), NULL, PROV_RSA_FULL, 0)) return; if (GetLastError()!=NTE_BAD_KEYSET) throw win32_error("CryptAcquireContext"); if (!CryptAcquireContext(&_hProv, _T("UN"), NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) throw win32_error("CryptAcquireContext"); } ~cryptapi() { if (!CryptReleaseContext(_hProv, 0)) throw win32_error("CryptReleaseContext"); } void test() { printf("rc2=%04x md5=%04x\n", CALG_RC2, CALG_MD5); cryptkey key; if (!CryptGenKey(_hProv, CALG_RC2, CRYPT_EXPORTABLE, &key)) throw win32_error("CryptGenKey"); printf("rc2 keylen=%d blocklen=%d\n", key.getdwparam(KP_KEYLEN), key.getdwparam(KP_BLOCKLEN)); } ByteVector decryptdata(const std::string& keystr, ByteVector& data) { crypthash hash; if (!CryptCreateHash(_hProv, CALG_MD5, 0, 0, &hash)) throw win32_error("CryptCreateHash"); if (!CryptHashData(hash, (const BYTE*)keystr.c_str(), keystr.size(), 0)) throw win32_error("CryptHashData"); cryptkey key; if (!CryptDeriveKey(_hProv, CALG_RC2, hash, CRYPT_EXPORTABLE|(128<<16), &key)) throw win32_error("CryptDeriveKey"); ByteVector out(data); DWORD size= out.size(); if (!CryptDecrypt(key, 0, FALSE, 0, &out.front(), &size)) throw win32_error("CryptDecrypt"); return out; } }; void usage() { printf("dec -n NUM -k HEXKEY hexdata\n"); } int main(int argc,char**argv) { int keynumber; std::string keystring; ByteVector data; try { for (int i=1 ; i