// ClientCDKey::EncryptKey // Encrypts into 8 byte buffer in 16 byte binary. Uses symmetric key built from product // name for encryption. bool ClientCDKey::EncryptKey(const __int64& theBufR) const { WTRACE("ClientCDKey::EncryptKey"); try { // Build symmetric key from product WDBG_LL("ClientCDKey::EncryptKey Creating symmetric key from product=" << mProduct); BFSymmetricKey aSymKey; CreateSymmetricKey(aSymKey); // Decrypt the key WDBG_LL("ClientCDKey::EncryptKey Encrypting CDKey."); BFSymmetricKey::CryptReturn anEncrypt(aSymKey.Encrypt(reinterpret_cast<const unsigned char*>(&theBufR), sizeof(theBufR))); auto_ptr<unsigned char> aDelP(anEncrypt.first); if (anEncrypt.second != BINARYKEY_LEN) { WDBG_LM("ClientCDKey::EncryptKey Encrypt of key has bad length."); return false; } // Fill BinKey with encrypted key mBinKey.assign(anEncrypt.first, anEncrypt.second); } catch (WONCrypt::CryptException& anExR) { WDBG_LH("ClientCDKey::EncryptKey exception encrypting key: " << anExR); return false; } return true; }
// ClientCDKey::DecryptKey // Decrypt 16 byte binary key into 8 byte buffer. Uses symmetric key built from product // name for decryption. bool ClientCDKey::DecryptKey(__int64& theBufR) { WTRACE("ClientCDKey::DecryptKey"); try { // Build symmetric key from product WDBG_LL("ClientCDKey::DecryptKey Creating symmetric key from product=" << mProduct); BFSymmetricKey aSymKey; CreateSymmetricKey(aSymKey); // Decrypt the key WDBG_LL("ClientCDKey::DecryptKey Decrypting CDKey."); BFSymmetricKey::CryptReturn aDecrypt(aSymKey.Decrypt(mBinKey.data(), mBinKey.size())); auto_ptr<unsigned char> aDelP(aDecrypt.first); if (aDecrypt.second != sizeof(theBufR)) { WDBG_LM("ClientCDKey::DecryptKey Decrypt of key has bad length."); return false; } // Fill buffer with decrypted key memcpy(static_cast<void*>(&theBufR), aDecrypt.first, sizeof(theBufR)); } catch (WONCrypt::CryptException& anExR) { WDBG_LH("ClientCDKey::DecryptKey exception decrypting key: " << anExR); return false; } return true; }
// ClientCDKey::CreateSymmetricKey // Creates a symmetric key from product name used to save/load CD-Key to/from // the registry. Symmetric key is created via a series of CRCs on the product. void ClientCDKey::CreateSymmetricKey(BFSymmetricKey& theSymKeyR) const { WTRACE("ClientCDKey::CreateSymmetricKey"); WDBG_LL("ClientCDKey::CreateSymmetricKey from product=" << mProduct); CRC16 aCRC; RawBuffer aBuf; // CRC the product and use it as 1st 2 bytes of key aCRC.Put(mProduct); unsigned short aCheckSum = aCRC.GetCRC(); WDBG_LL("ClientCDKey::CreateSymmetricKey First CRC=" << aCheckSum); aBuf.assign(reinterpret_cast<unsigned char*>(&aCheckSum), sizeof(aCheckSum)); // CRC each of 1st 3 chars of product and add them to key. for (int i=0; (i < 3) && (i < mProduct.size()); i++) { aCRC.Put(static_cast<unsigned char>(mProduct[i])); aCheckSum = aCRC.GetCRC(); WDBG_LL("ClientCDKey::CreateSymmetricKey Add CRC=" << aCheckSum); aBuf.append(reinterpret_cast<unsigned char*>(&aCheckSum), sizeof(aCheckSum)); } // Create the key WDBG_LL("ClientCDKey::CreateSymmetricKey Buf=" << aBuf); theSymKeyR.Create(aBuf.size(), aBuf.data()); }
int main(int argc, const char** argv) { //WDBG_INIT(WDBG_LIBLOW, "CryptTest", NULL, "E:\\Logs"); { cout << endl << "Testing Random Number Generator..." << endl; for (int i=1; i <= 100; i++) { unsigned short aShort = Randomizer::GetShort(); cout << std::hex << aShort << std::dec << " "; if ((i % 5) == 0) cout << endl; } cout << endl; } { cout << endl << "Testing Key Classes..." << endl; KeySet aKeySet; aKeySet.insert(new BFSymmetricKey(CryptKeyBase::KEYLEN_DEF)); aKeySet.insert(new BFSymmetricKey(4)); BFSymmetricKey aKey(12); aKeySet.insert(new BFSymmetricKey(aKey.GetKeyLen(), aKey.GetKey())); aKeySet.insert(new EGPrivateKey(CryptKeyBase::KEYLEN_DEF)); aKeySet.insert(new EGPrivateKey(4)); EGPrivateKey aPvKey(12); EGPrivateKey aPvKey1(0); aKeySet.insert(new EGPrivateKey(aPvKey.GetKeyLen(), aPvKey.GetKey())); aKeySet.insert(new EGPrivateKey(aPvKey1)); const EGPublicKey& aPubKey = dynamic_cast<const EGPublicKey&>(aPvKey1.GetPublicKey()); aKeySet.insert(new EGPublicKey(aPvKey)); aKeySet.insert(new EGPublicKey(aPubKey)); // Output keys KeySet::iterator anItr(aKeySet.begin()); for (int i=1; anItr != aKeySet.end(); i++) { cout << "Key " << i << ": " << *(*anItr) << endl; delete *anItr; anItr = aKeySet.erase(anItr); } cout << endl; } { cout << endl << "Testing SymmetricCrypt..." << endl; BFSymmetricKey* myKey = new BFSymmetricKey(8); BFSymmetricKey* badKey = new BFSymmetricKey(12); char* iStr = "Mike has no life!"; BFSymmetricKey::CryptReturn encrypt(myKey->Encrypt(reinterpret_cast<unsigned char*>(iStr), strlen(iStr)+1)); BFSymmetricKey::CryptReturn decrypt(myKey->Decrypt(encrypt.first, encrypt.second)); cout << "Input: " << iStr << endl; cout << "Output: " << reinterpret_cast<const char*>(decrypt.first ? decrypt.first : (const unsigned char*)"NULL") << endl; delete encrypt.first; delete decrypt.first; delete myKey; delete badKey; } { cout << endl << "Testing ElGamal Crypt..." << endl; EGPrivateKey* myPrivKey = new EGPrivateKey(8); EGPrivateKey* badKey = new EGPrivateKey(12); EGPublicKey* myPubKey = new EGPublicKey(*myPrivKey); char* iStr = "Mike has no life!"; EGPublicKey::CryptReturn encrypt(myPubKey->Encrypt(reinterpret_cast<unsigned char*>(iStr), strlen(iStr)+1)); EGPrivateKey::CryptReturn decrypt(myPrivKey->Decrypt(encrypt.first, encrypt.second)); cout << "Input: " << iStr << endl; cout << "Output: " << reinterpret_cast<const char*>(decrypt.first ? decrypt.first : (const unsigned char*)"NULL") << endl; delete encrypt.first; delete decrypt.first; delete myPrivKey; delete myPubKey; delete badKey; } { cout << endl << "Testing ElGamal Sigs..." << endl; EGPrivateKey* myPrivKey = new EGPrivateKey(8); EGPrivateKey* badKey = new EGPrivateKey(12); EGPublicKey* myPubKey = new EGPublicKey(*myPrivKey); char* iStr = "Mike has no life!"; EGPrivateKey::CryptReturn sig(myPrivKey->Sign(reinterpret_cast<unsigned char*>(iStr), strlen(iStr)+1)); int tstSig = myPubKey->Verify(sig.first, sig.second, reinterpret_cast<unsigned char*>(iStr), strlen(iStr)+1); cout << "Msg: " << iStr << " sigLen=" << sig.second << endl; cout << "Verify: " << (tstSig ? "TRUE" : "FALSE") << endl; delete sig.first; delete myPrivKey; delete myPubKey; } return 0; }