📄 crypto.cpp
字号:
#include "StdAfx.h"
#include ".\crypto.h"
CCrypto::CCrypto(void)
{
hCryptProv = NULL;
hPublicKey = NULL;
hXchgKey = NULL;
hKey = NULL;
pbSessionKeyBlob = NULL;
pbPublicKeyBlob = NULL;
}
CCrypto::~CCrypto(void)
{
}
BOOL CCrypto::GetCSP(LPCTSTR strUserName)
{
if (hCryptProv != NULL) return TRUE;
if(CryptAcquireContext(
&hCryptProv,
strUserName,
MS_DEF_RSA_SCHANNEL_PROV,
PROV_RSA_SCHANNEL,
0))
{
return TRUE;
}
else
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if(CryptAcquireContext(
&hCryptProv,
strUserName,
MS_DEF_RSA_SCHANNEL_PROV,
PROV_RSA_SCHANNEL,
CRYPT_NEWKEYSET))
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
}
void CCrypto::ReleaseCSP(void)
{
if (hCryptProv != NULL)
CryptReleaseContext(hCryptProv,0);
hCryptProv = NULL;
}
BOOL CCrypto::GetRSAKey(void)
{
if (pbPublicKeyBlob != NULL) return TRUE;
if(!CryptGenKey(
hCryptProv,
CALG_RSA_KEYX,
(512<<16)|CRYPT_EXPORTABLE,
&hXchgKey))
{
DWORD dwErrorCode = GetLastError();
return FALSE;
}
BOOL bSuccess = CryptExportKey(hXchgKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyBlobLen);
if (!bSuccess)
{
CryptDestroyKey(hXchgKey);
hXchgKey = NULL;
return FALSE;
}
pbPublicKeyBlob = (PBYTE)malloc(dwPublicKeyBlobLen);
bSuccess = CryptExportKey(hXchgKey, NULL, PUBLICKEYBLOB, 0, pbPublicKeyBlob, &dwPublicKeyBlobLen);
if (!bSuccess)
{
free(pbPublicKeyBlob);
pbPublicKeyBlob = NULL;
CryptDestroyKey(hXchgKey);
hXchgKey = NULL;
}
return TRUE;
}
BOOL CCrypto::GetSessionKey(void)
{
if (pbSessionKeyBlob != NULL) return TRUE;
if(!CryptGenKey(
hCryptProv,
CALG_3DES,
CRYPT_EXPORTABLE,
&hKey))
{
DWORD dwErrorCode = GetLastError();
return FALSE;
}
BOOL bSuccess = CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, NULL, &dwSessionKeyBlobLen);
if (!bSuccess)
{
DWORD dwErrorCode = GetLastError();
ERROR_INVALID_HANDLE;
ERROR_INVALID_PARAMETER;
ERROR_MORE_DATA;
NTE_BAD_FLAGS;
NTE_BAD_KEY ;
NTE_BAD_KEY_STATE ;
NTE_BAD_PUBLIC_KEY ;
NTE_BAD_TYPE ;
NTE_BAD_UID ;
NTE_NO_KEY ;
CryptDestroyKey(hKey);
hKey = NULL;
return FALSE;
}
pbSessionKeyBlob = (PBYTE)malloc(dwSessionKeyBlobLen);
bSuccess = CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, pbSessionKeyBlob, &dwSessionKeyBlobLen);
if (!bSuccess)
{
free(pbSessionKeyBlob);
pbSessionKeyBlob = NULL;
CryptDestroyKey(hKey);
hKey = NULL;
}
return TRUE;
}
void CCrypto::ReleaseKeys(void)
{
if (hPublicKey != NULL) CryptDestroyKey(hPublicKey);
hPublicKey = NULL;
if (hXchgKey != NULL) CryptDestroyKey(hXchgKey);
hXchgKey = NULL;
if (hKey != NULL) CryptDestroyKey(hKey);
hKey = NULL;
if (pbSessionKeyBlob != NULL) free(pbSessionKeyBlob);
pbSessionKeyBlob = NULL;
if (pbPublicKeyBlob != NULL) free(pbPublicKeyBlob);
pbPublicKeyBlob = NULL;
}
BOOL CCrypto::ImportPublicKey(void)
{
if (hPublicKey != NULL) return TRUE;
BOOL bResult = CryptImportKey(hCryptProv, pbPublicKeyBlob, dwPublicKeyBlobLen, 0, 0, &hPublicKey);
if (!bResult) return FALSE;
}
BOOL CCrypto::ImportSessionKey(void)
{
if (hKey != NULL) return TRUE;
BOOL bResult = CryptImportKey(hCryptProv, pbSessionKeyBlob, dwSessionKeyBlobLen, hXchgKey, 0, &hKey);
return bResult;
}
void CCrypto::CopyExportedPublicKeyFrom(const CCrypto & crypto)
{
if (pbPublicKeyBlob != NULL) return;
dwPublicKeyBlobLen = crypto.dwPublicKeyBlobLen;
pbPublicKeyBlob = (PBYTE)malloc(dwPublicKeyBlobLen);
memcpy(pbPublicKeyBlob, crypto.pbPublicKeyBlob, dwPublicKeyBlobLen);
}
void CCrypto::CopyExportedSessionKeyFrom(const CCrypto & crypto)
{
if (pbSessionKeyBlob != NULL) return;
dwSessionKeyBlobLen = crypto.dwSessionKeyBlobLen;
pbSessionKeyBlob = (PBYTE)malloc(dwSessionKeyBlobLen);
memcpy(pbSessionKeyBlob, crypto.pbSessionKeyBlob, dwSessionKeyBlobLen);
}
#define BLOCKLEN 24
BOOL CCrypto::EncryptData(CString & strData/*in out*/)
{
CString strSrc;
int nLenWant = (strData.GetLength()/BLOCKLEN)*BLOCKLEN;
if (strData.GetLength()%BLOCKLEN != 0) nLenWant += BLOCKLEN;
char *buffer = strSrc.GetBufferSetLength(nLenWant);
ZeroMemory(buffer, nLenWant);
memcpy(buffer, strData, strData.GetLength());
DWORD dwCount = strData.GetLength();
DWORD dwBufferLen = nLenWant;
BOOL bResult = CryptEncrypt(hKey, 0, TRUE, 0, (BYTE *)buffer, &dwCount, dwBufferLen);
DWORD dwErrorCode = 0;
if (!bResult) dwErrorCode = GetLastError();
strSrc.ReleaseBufferSetLength(dwCount);
strData = strSrc;
ERROR_INVALID_HANDLE ;//One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER ;//One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID ;//The hKey session key specifies an algorithm that this CSP does not support.
NTE_BAD_DATA ;//The data to be encrypted is invalid. For example, when a block cipher is used and the Final flag is FALSE, the value specified by pdwDataLen must be a multiple of the block size.
NTE_BAD_FLAGS ;//The dwFlags parameter is nonzero.
NTE_BAD_HASH ;//The hHash parameter contains an invalid handle.
NTE_BAD_HASH_STATE ;//An attempt was made to add data to a hash object that is already marked "finished."
NTE_BAD_KEY ;//The hKey parameter does not contain a valid handle to a key.
NTE_BAD_LEN ;//The size of the output buffer is too small to hold the generated ciphertext.
NTE_BAD_UID ;//The CSP context that was specified when the key was created cannot be found.
NTE_DOUBLE_ENCRYPT ;//The application attempted to encrypt the same data twice.
NTE_FAIL ;//The function failed in some unexpected way.
NTE_NO_MEMORY ;//
return bResult;
}
BOOL CCrypto::DecryptData(CString & strData/*in out*/)
{
char *buffer = strData.GetBuffer();
DWORD dwCount = strData.GetLength();
BOOL bResult = CryptDecrypt(hKey, 0, TRUE, 0, (BYTE *)buffer, &dwCount);
strData.ReleaseBuffer(dwCount);
DWORD dwErrorCode = 0;
if (!bResult) dwErrorCode = GetLastError();
return bResult;
}
void CCrypto::PrintRSAKeyPair(CString & strPublicKey_e, CString & strPublicKey, CString & strPrivateKey)
{
RSAPUBKEY *rsapubkey = (RSAPUBKEY *)(pbPublicKeyBlob + sizeof(PUBLICKEYSTRUC));
BYTE *modulus = pbPublicKeyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
strPublicKey_e.Format("0x%X", rsapubkey->pubexp);
strPublicKey = "0x";
for (int i=0; i<(rsapubkey->bitlen/8); i++)
{
CString strTmp;
strTmp.Format("%02X ", modulus[i]);
strPublicKey += strTmp;
}
PBYTE pbPrivateKeyBlob;
DWORD dwPrivateKeyBlobLen = 0;
BOOL bSuccess = CryptExportKey(hXchgKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyBlobLen);
pbPrivateKeyBlob = (PBYTE)malloc(dwPrivateKeyBlobLen);
bSuccess = CryptExportKey(hXchgKey, NULL, PRIVATEKEYBLOB, 0, pbPrivateKeyBlob, &dwPrivateKeyBlobLen);
rsapubkey = (RSAPUBKEY *)(pbPrivateKeyBlob + sizeof(PUBLICKEYSTRUC));
BYTE *privateExponent = pbPrivateKeyBlob + sizeof(PUBLICKEYSTRUC) + \
sizeof(RSAPUBKEY) + rsapubkey->bitlen/8 + (rsapubkey->bitlen/16) * 5;
strPrivateKey = "0x";
for (int i=0; i<rsapubkey->bitlen/8; i++)
{
CString strTmp;
strTmp.Format("%02X ", privateExponent[i]);
strPrivateKey += strTmp;
}
free(pbPrivateKeyBlob);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -