/***********************************************************************/ /* Copyright (C) 2002 Definitive Solutions, Inc. All Rights Reserved. */ /* THIS COMPUTER PROGRAM IS PROPRIETARY AND CONFIDENTIAL TO DEFINITIVE */ /* SOLUTIONS, INC. AND ITS LICENSORS AND CONTAINS TRADE SECRETS OF */ /* DEFINITIVE SOLUTIONS, INC. THAT ARE PROVIDED PURSUANT TO A WRITTEN */ /* AGREEMENT CONTAINING RESTRICTIONS ON USE AND DISCLOSURE. ANY USE, */ /* REPRODUCTION, OR TRANSFER EXCEPT AS PROVIDED IN SUCH AGREEMENT */ /* IS STRICTLY PROHIBITED. */ /***********************************************************************/ ///////////////////////////////////////////////////////////////////////////// // How to add this class to your application. // // Add MyCrypto.cpp and MyCrypto.h to your project in the usual folders. // // This class implements RSA RC2 block encryption unded MS CryptoAPI. This is // by definition a 40-bit encryption scheme. // // To encrypt a CString, do this: // // MyCrypto mc; // VERIFY(mc.Initialize("ThisIsMySecretPassword")); // // CString sPlainText("ThisIsSecretText"); // DWORD dwSize(mc.GetRequiredCryptBufferSize(sPlainText.GetLength()); // PBYTE pbyCrypt = new BYTE[dwSize]; // DWORD dwLenCrypt(0); // VERIFY(mc.Encrypt("This is a Secret", pbyCrypt, dwLenCrypt); // /////////////////////////////////////////////////////////////////////////////// #if !defined(MYCRYPTOH_EA025731_0B61_11d6_8AB2_00B0D0529ED2_INCLUDED_) #define MYCRYPTOH_EA025731_0B61_11d6_8AB2_00B0D0529ED2_INCLUDED_ #pragma once #define _WIN32_WINNT 0x0400 // Guard defines for MSCrypto (Q169088). #include "Wincrypt.h" // MS CryptoAPI. ///////////////////////////////////////////////////////////////////////////// // MyCrypto class MyCrypto { // Construction. public: MyCrypto(); virtual ~MyCrypto(); // Deliberately declared but not defined. private: MyCrypto(const MyCrypto& rhs); MyCrypto& operator=(const MyCrypto& rhs); // Interface. public: // One of the 'Initialize()' overloads must be called exactly once before // any other method, with a non-empty password. This overload accepts a // byte array. bool Initialize(IN const PBYTE pbyPassword, IN DWORD dwLenPassword, IN LPCTSTR lpctstrProviderName = NULL); // One of the 'Initialize()' overloads must be called exactly once before // any other method, with a non-empty password. This overload accepts a // CString. bool Initialize(IN const CString& sPassword, IN LPCTSTR lpctstrProviderName = NULL); // Given an array of plaintext bytes (and the size of the array), this // encrypts it, and copies it to the client-allocated 'pbyCrypt' array. // It is assumed that the client has guaranteed the 'pbyCrypt' array is // large enough (by using the GetRequiredCryptBufferSize() method). The // number of actual encrypted bytes is returned in 'dwLenCrypt'. bool Encrypt(IN const PBYTE pbyPlain, IN DWORD dwLenPlain, IN PBYTE pbyCrypt, OUT DWORD& dwLenCrypt); // Given a CString of plaintext, this encrypts it, and copies it to the // client-allocated 'pbyCrypt' array. It is assumed that the client has // guaranteed the 'pbyCrypt' array is large enough (by using the // GetRequiredCryptBufferSize() method). The number of actual encrypted // bytes is returned in 'dwLenCrypt'. bool Encrypt(IN const CString& sPlain, IN PBYTE pbyCrypt, OUT DWORD& dwLenCrypt); // Given a CString of plaintext, this encrypts it, converts the encrypted // text to decimal numerals, and copies it to the sent CString 'sCrypt'. // The number of actual encrypted bytes can be determined using // CString::GetLength(). This method is useful for storing encrypted // information in, for example, an INI file. bool Encrypt(IN const CString& sPlain, OUT CString& sCrypt); // Given an array of encrypted bytes (and the size of the array), this // decrypts it, and copies it to the client-allocated 'pbyPlain' array. // It is assumed that the client has guaranteed the 'pbyPlain' array is // large enough. The number of actual plaintext bytes is returned in // 'dwLenPlain'. bool Decrypt(IN const PBYTE pbyCrypt, IN DWORD dwLenCrypt, IN PBYTE pbyPlain, OUT DWORD& dwLenPlain); // Given an array of encrypted bytes (and the size of the array), this // decrypts it, and copies it to the sent 'sPlain' CString. The number of // actual plaintext bytes can be determined using CString::GetLength(). bool Decrypt(IN const PBYTE pbyCrypt, IN DWORD dwLenCrypt, OUT CString& sPlain); // Given a CString containing decimal numberals, this converts it to an // array of encrypted bytes, decrypts that array, and copies it to the sent // 'sPlain' CString. The number of actual plaintext bytes can be determined // using CString::GetLength(). This method is useful for retreiving // encrypted information from, for example, an INI file. bool Decrypt(IN const CString& sCrypt, OUT CString& sPlain); // When encrypting, the client will need to know how big to make the // buffer that will hold the encrypted data. This method will return that // value, based on the size of the plaintext. (This does not imply that // the *entire* buffer will be filled with cryptotext.) // // When decrypting, the client can safely assume that the plaintext array // can be the same size as the encrypted array. static DWORD GetRequiredCryptBufferSize(IN DWORD dwLenPlain); // Implementation. private: bool EncryptOneChunk(const PBYTE pbyPlain, DWORD dwLenPlain, PBYTE pbyCrypt, DWORD& dwLenCrypt, bool bFinalChunk); bool DecryptOneChunk(const PBYTE pbyCrypt, DWORD dwLenCrypt, PBYTE pbyPlain, DWORD& dwLenPlain, bool bFinalChunk); CString GetSysErrorString(int nErrSent = 0); // Constants. private: // ENCRYPT_BLOCK_SIZE is fixed at 8 bytes for RC2. static const DWORD MYCRYPTO_BLOCK_SIZE; // The maximum number of bytes that can be encoded with one call. This must // be a multiple of ENCRYPT_BLOCK_SIZE. static const DWORD MYCRYPTO_CHUNK_SIZE; // The buffer size. If a block cipher is used, it must have room for an // extra block. "If a block cipher is used, the ciphertext is up to // a 'block length' larger than the plaintext." static const DWORD MYCRYPTO_BUFFER_SIZE; // A decimal byte requires at most three digits to display: 000 through 255. static const DWORD DIGITS_PER_ENCRYPTED_BYTE; // Data. private: HCRYPTPROV m_hCryptProv; // CSA handle. HCRYPTHASH m_hHash; // Hash handle. HCRYPTKEY m_hKey; // Key handle. enum Mode { Unknown = 0, Encrypting, Decrypting }; Mode m_Mode; // Needed as you mustn't do both // on the same HCRYPTPROV. This // is set by Encrypt() and // Decrypt(). }; #endif // MYCRYPTOH_EA025731_0B61_11d6_8AB2_00B0D0529ED2_INCLUDED_