VC加密代码如下: 
STDMETHODIMP CAdvTEncrypt::Encrypt(VARIANT *bstrPlainText, VARIANT *bstrPassword, VARIANT *vCipherText) 

BYTE *pbData; 
BYTE *pbPassword; 
HCRYPTPROV hProv  = 0; 
HCRYPTHASH hHash  = 0; 
HCRYPTKEY hKey    = 0; 
    DWORD dwCryptDataLen = 0; 
DWORD dwDataLen = 0; 
DWORD dwError = 0; 
TCHAR  buffer[200]; 
TCHAR strHex[HexDataLength+1]; USES_CONVERSION; 
if ( bstrPlainText->vt != VT_BSTR || bstrPassword->vt != VT_BSTR ) 
return E_INVALIDARG; // The following will cause trouble if you use impersonation to access network drive, remove it 
// RevertToSelf(); // comments added: terminates the impersonation of a client application dwDataLen = SysStringLen(bstrPlainText->bstrVal); 
pbData = (BYTE*)OLE2A(bstrPlainText->bstrVal); 
pbPassword = (BYTE*)OLE2A(bstrPassword->bstrVal); LPCTSTR pszContainer = _T("MStarAdvisorEncrypt\0"); 
LPCTSTR pszProvider = MS_DEF_PROV; 
ALG_ID algId = ENCRYPT_ALGORITHM; 
DWORD dwFlags = CRYPT_MACHINE_KEYSET; 
ALG_ID hashAlgId = CALG_MD5; 
DWORD dwFlagsCryptDeriveKey = 0; dwCryptDataLen = dwDataLen; 
PBYTE pCipherText = pbData; BYTE arrCipherText[constCookieLength]; 
switch (enumAlgId) 

case RC: 
RevertToSelf(); //need to impersonate the account for passwd encryption project, otherwise the awslogin reset passwd in user profile will not work 
pszContainer = _T("MStarAdvisorEncrypt\0"); 
pszProvider = MS_DEF_PROV; 
algId = ENCRYPT_ALGORITHM; 
dwFlags = CRYPT_MACHINE_KEYSET; 
hashAlgId = CALG_MD5; 
dwFlagsCryptDeriveKey = 0; 
break; 
case TDES: 
pszContainer = NULL; // when using CRYPT_VERIFYCONTEXT, must set this to NULL 
pszProvider = MS_ENHANCED_PROV; 
algId = CALG_3DES; 
dwFlags = CRYPT_VERIFYCONTEXT; 
hashAlgId = CALG_SHA; 
dwFlagsCryptDeriveKey = 0;//CRYPT_EXPORTABLE; //(168) < <16; 
//  ENCRYPT_BLOCK_SIZE = 8; 
dwDataLen = constCookieLength; 
pCipherText = arrCipherText; 
memcpy(pCipherText, pbData, dwDataLen); break; 
case AES: 
break; 
default: 
pszContainer = _T("MStarAdvisorEncrypt\0"); 
pszProvider = MS_DEF_PROV; 
algId = ENCRYPT_ALGORITHM; 
dwFlags = CRYPT_MACHINE_KEYSET; 
hashAlgId = CALG_MD5; 
dwFlagsCryptDeriveKey = 0; 

//(MS_DEF_PROV, PROV_RSA_FULL) this default cryptographic service provider 
//currently using 40 bit session key and 512 bit public key 
// Get handle to the default provider. 
    if (! CryptAcquireContext(&hProv, pszContainer, 
pszProvider, PROV_RSA_FULL, dwFlags)) 

LPVOID lpMsgBuf1 = NULL; 
LPVOID lpMsgBuf2 = NULL; dwError = GetLastError(); 
DWORD dwError1 = 0; FormatMessage( 
FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM | 
FORMAT_MESSAGE_IGNORE_INSERTS, 
NULL, 
dwError, 
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
(LPTSTR) &lpMsgBuf1, 
0, NULL ); if (! CryptAcquireContext(&hProv, pszContainer, 
pszProvider, PROV_RSA_FULL, (CRYPT_NEWKEYSET | dwFlags))) 

dwError1 = GetLastError(); FormatMessage( 
FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM | 
FORMAT_MESSAGE_IGNORE_INSERTS, 
NULL, 
dwError1, 
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
(LPTSTR) &lpMsgBuf2, 
0, NULL ); _stprintf(buffer, _T("Error %x during CryptAcquireContext: [%s] | after CRYPT_NEWKEYSET: Error %x: [%s]"), dwError, (LPCTSTR)lpMsgBuf1, dwError1, (LPCTSTR)lpMsgBuf2); if (lpMsgBuf1) 
LocalFree(lpMsgBuf1); if (lpMsgBuf2) 
LocalFree(lpMsgBuf2); return Error(buffer); 

} // Create a hash object. 
if ( ! CryptCreateHash(hProv, hashAlgId, 0, 0, &hHash)) { 
dwError = GetLastError(); 
_stprintf(buffer, _T("Error %x during CryptCreateHash"), dwError); 
return Error(buffer); 
} // Hash in the password. 
if ( ! CryptHashData(hHash, pbPassword, SysStringLen(bstrPassword->bstrVal), 0)) { 
dwError = GetLastError(); 
_stprintf(buffer, _T("Error %x during CryptHashData"), dwError); 
return Error(buffer); 
} // Derive a session key from the hash object. 
if ( ! CryptDeriveKey(hProv, algId, hHash, dwFlagsCryptDeriveKey, &hKey)) { 
dwError = GetLastError(); 
_stprintf(buffer, _T("Error %x during CryptDeriveKey"), dwError); 
return Error(buffer); 
} // Destroy hash object. 
CryptDestroyHash(hHash); 
hHash = 0; // to do, shall we set IV and Mode for TDES (It is block cyper 
// set IV and set Mode using the function below 
// CryptSetKeyParam(m_hKey, dwParam, pbData, dwFlags) 
if (TDES == enumAlgId) 

// Set Mode 
DWORD mode = CRYPT_MODE_CBC; 
if (!CryptSetKeyParam(hKey, KP_MODE, (BYTE *) &mode, 0)) 

dwError = GetLastError(); 
_stprintf(buffer, _T("Error %x during CryptSetKeyParam KP_MODE"), dwError); 
return Error(buffer); } 
} BYTE bKeys[22] = {0}; 
CopyMemory(bKeys, (BYTE*)hKey, 21); 
printf("\r\n---------------\r\n"); 
for (int i=0; i <22; ++i) 

printf(_T(",%d"), (int)bKeys[i]); 

printf("\r\n---------------\r\n"); // Encrypt the Data. 
if ( ! CryptEncrypt(hKey, 0, true, 0, pCipherText, &dwCryptDataLen, dwDataLen)) { 
dwError = GetLastError(); 
_stprintf(buffer, _T("Error %x during CryptEncrypt"), dwError); 
switch (dwError) 

case ERROR_INVALID_HANDLE: 
_stprintf(buffer, _T("Error %x (ERROR_INVALID_HANDLE) during CryptEncrypt"), dwError); 
return Error(buffer); 
case ERROR_INVALID_PARAMETER: 
_stprintf(buffer, _T("Error %x (ERROR_INVALID_PARAMETER) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_ALGID: 
_stprintf(buffer, _T("Error %x (NTE_BAD_ALGID) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_DATA: 
_stprintf(buffer, _T("Error %x (NTE_BAD_DATA) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_FLAGS: 
_stprintf(buffer, _T("Error %x (NTE_BAD_FLAGS) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_HASH: 
_stprintf(buffer, _T("Error %x (NTE_BAD_HASH) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_HASH_STATE: 
_stprintf(buffer, _T("Error %x (NTE_BAD_HASH_STATE) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_KEY: 
_stprintf(buffer, _T("Error %x (NTE_BAD_KEY) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_LEN: 
_stprintf(buffer, _T("Error %x (NTE_BAD_LEN) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_BAD_UID: 
_stprintf(buffer, _T("Error %x (NTE_BAD_UID) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_DOUBLE_ENCRYPT: 
_stprintf(buffer, _T("Error %x (NTE_DOUBLE_ENCRYPT) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_FAIL: 
_stprintf(buffer, _T("Error %x (NTE_FAIL) during CryptEncrypt"), dwError); 
return Error(buffer); 
case NTE_NO_MEMORY: 
_stprintf(buffer, _T("Error %x (NTE_NO_MEMORY) during CryptEncrypt"), dwError); 
return Error(buffer); 
default: 
_stprintf(buffer, _T("Error %x () during CryptEncrypt"), dwError); 
return Error(buffer); 

return Error(buffer); 
} // Place Encrypted Data into a VARIANT SAFEARRAY of VARIANT BYTE 
#if 0 
SAFEARRAYBOUND rgsabound[] = {dwCryptDataLen, 0}; 
psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound); 
VARIANT* rgElems; 
SafeArrayAccessData(psa, (LPVOID*)&rgElems); 
for(DWORD i=0;i <dwCryptDataLen;i++){ 
VariantInit(&rgElems[i]); 
rgElems[i].vt = VT_UI1; 
rgElems[i].uiVal = pbData[i]; 

SafeArrayUnaccessData(psa); 
#endif #if 0 
CComBSTR bstr; 
TCHAR szMsg[10]; 
for(DWORD i=0;i <dwCryptDataLen;i++) 

_stprintf(szMsg,_T("%c"),pbData[i]); 
bstr.Append(T2OLE(szMsg)); 

#endif // No need to terminate BYTE array 
//Terminate the string with a null 
//pCipherText[dwCryptDataLen] = NULL; for(DWORD i=0;i <dwCryptDataLen;i++) 
ATLTRACE("Encrypt:%d\n",pCipherText[i]); 
GetHex(pCipherText, strHex, dwCryptDataLen); 
VariantInit(vCipherText); 
vCipherText->vt = VT_BSTR ; 
vCipherText->bstrVal = ::SysAllocString(T2OLE(strHex)); // Destroy session key. 
    if(hKey) CryptDestroyKey(hKey); // Release provider handle. 
    if(hProv) CryptReleaseContext(hProv, 0); return S_OK; 
} void CAdvTEncrypt::GetHex(BYTE* strText, LPTSTR strHex, int nLen) 

int i, nChar, nDiv, nMod; 
for (i=0;i <nLen;i++) 

nChar = strText[i]; 
std::cout < < nChar < <"\r\n"; 
nDiv = nChar/16; 
nMod = nChar%16; 
if (nDiv > 9 && nDiv < 16) 
strHex[i*2] = 'A' + nDiv; 
else 
strHex[i*2] = '0' + nDiv; 
if (nMod > 9 && nMod < 16) 
strHex[i*2+1] = 'A' + nMod; 
else 
strHex[i*2+1] = '0' + nMod; 

strHex[i*2] = '\0'; 
}

解决方案 »

  1.   

    密钥生成的算法如下:Let n be the required derived key length, in bytes. The derived key is the first n bytes of the hash value after the hash computation has been completed by CryptDeriveKey. If the hash is not a member of the SHA-2 family and the required key is for either 3DES or AES, the key is derived as follows:   1. Form a 64-byte buffer by repeating the constant 0x36 64 times. Let k be the length of the hash value that is represented by the input parameter hBaseData. Set the first k bytes of the buffer to the result of an XOR operation of the first k bytes of the buffer with the hash value that is represented by the input parameter hBaseData.
       2. Form a 64-byte buffer by repeating the constant 0x5C 64 times. Set the first k bytes of the buffer to the result of an XOR operation of the first k bytes of the buffer with the hash value that is represented by the input parameter hBaseData.
       3. Hash the result of step 1 by using the same hash algorithm as that used to compute the hash value that is represented by the hBaseData parameter.
       4. Hash the result of step 2 by using the same hash algorithm as that used to compute the hash value that is represented by the hBaseData parameter.
       5. Concatenate the result of step 3 with the result of step 4.
       6. Use the first n bytes of the result of step 5 as the derived key.