The Basic Challenge protocol works on the principle of shared secrets. The protocol requires that at least four 32-bit secrets be stored in each activation key that participates in this protection scheme. These secrets, chosen by the software publisher, are encrypted within the activation key itself, with only the license provider knowing how to decrypt them. In order to perform the challenge, the product generates a random value and an index into the list of secrets, which it passes as the challenge to the license provider. The license provider combines the random value with the selected secret from the activation key. This data is fed into the MD4 message digest algorithm (one-way encrypting scheme), yielding a unique message digest. The message digest is returned as the response to the challenge. The product then computes the expected message digest and compares it with the one returned by the license provider.
class TBasicChallenge : public TProviderOperation { // Copyright (C) 1995 Taligent, Inc. All rights reserved. public: //................................................................. // Public globals. static const TStandardText kOperationType; //................................................................. // Constructors and destructor TBasicChallenge(); TBasicChallenge(const unsigned long indexOfSecret,const unsigned long randomNumber); TBasicChallenge(const TBasicChallenge&); virtual ~TBasicChallenge(); //................................................................. // operator overloads. TBasicChallenge&operator= (const TBasicChallenge&); //................................................................. // MCollectible overrides. TStream& operator>>=(TStream& toWhere) const; TStream& operator<<= (TStream& fromWhere); //................................................................. // TBasicChallenge specific operations. virtual void GetOperationType(TText& type) const; virtual unsigned long GetIndexOfSecret() const; virtual void SetSecret (const TPrimitiveTypeArray<unsigned char>& message); virtual Boolean CompareSecret(const TPrimitiveTypeArray<unsigned char>& message) const; //................................................................. // Public data members allow direct access by paranoid clients // which directly implement CompareSecret() within their own code. unsigned long fIndexOfSecret; unsigned long fRandomNumber; TMD4 fDigest; private: };
GetIndexOfSecret returns the index into the list of secrets that was specified at object construction time. This member function is typically used by the license provider to identify the secret that should be used in executing the TBasicChallenge operation.