// UkeyJBD2006Encrypt.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <wincrypt.h> #include <crtdbg.h> #include "UkeyJBD2006Encrypt.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //工行UKey[金邦达2006] //金邦达2006的CSP驱动做的不好, 至少在我的开发机上兼容性有问题. //金邦达2006CSP驱动有BUG, 经常性的不能连接CSP上下文. //连接上下文时, 有时会阻塞;有时会会报错 //好像有限制, 插入Key一段时间后, 再连接上下文, 就连接不上 //金邦达自己的工具箱都点击后,界面都出不来. 真难用 //重新启动计算机后,也不行需要卸载驱动后,重新安装驱动. //农行UKey[华大] //我农行的Key里没有证书, 好长时间不用了 //if (!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey)), 得加密证书句柄失败 //华大Key驱动做的不错, 问我口令时,我忘了, 还有3次被锁定,不敢再实验. //招行UKey[无CSP] //用CSP侦测工具看不到招行Key对应的CSP, 看来招行的UKey只用UkeyDll接口调用 //加密过程相同, 换成别的UKey. //用CSP侦测工具, 得到CSP提供者和容器名称 #define G_CS_CSP_PROVIDER "您真实的CSP提供者名称" #define G_CS_CSP_CONTAINER "您真实的CSP容器名称" #define G_DW_LEN_BUFFER 1024 #define G_CS_ORIGINAL_TXT "原文: 用CSP加密" ///////////////////////////////////////////////////////////////////////////// // The one and only application object CWinApp theApp; using namespace std; /** @para PBYTE pBufData, 原文Buffer @para DWORD & dwLenBufDataToEncrypt, 原文长度 @para DWORD dwLenBuf, 承载原文的Buffer长度, 这个长度要大于原文长度, 因为(密文长度>=原文长度) @return S_OK, 成功 @return S_FALSE, 失败 */ int nFnUkeyEncrypt(PBYTE pBufData, DWORD &dwLenBufDataToEncrypt, DWORD dwLenBuf); /** @para PBYTE pBufData, 密文Buffer @para DWORD dwLenBufDataToDecrypt, 密文长度 @para DWORD dwLenBuf, 承载密文Buffer长度, 这个长度要<=密文长度, 因为(原文长度<=密文长度) @return S_OK, 成功 @return S_FALSE, 失败 */ int nFnUkeyDecrypt(PBYTE pBufData, DWORD dwLenBufDataToDecrypt, DWORD &dwLenBufOrginalContent); //tools functions int FnPrintBuffer(PCHAR pcPrefix, PBYTE pbcBuffer, DWORD dwLenBuffer); int _tmain(int argc, TCHAR *argv[], TCHAR *envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } else { DWORD dwLenBuf = G_DW_LEN_BUFFER; PBYTE pBuf = new BYTE[dwLenBuf]; memset(pBuf, 0, dwLenBuf); strcpy((PCHAR)pBuf, G_CS_ORIGINAL_TXT); DWORD dwLenOriginalText = strlen(G_CS_ORIGINAL_TXT); printf("加密前原文:[%s]/n", G_CS_ORIGINAL_TXT); DWORD dwLenEncryptText = dwLenOriginalText; nFnUkeyEncrypt(pBuf, dwLenEncryptText, dwLenBuf); FnPrintBuffer("密文", pBuf, dwLenEncryptText); DWORD dwLenOriginalTextByDecrypt = 0; nFnUkeyDecrypt(pBuf, dwLenEncryptText, dwLenOriginalTextByDecrypt); *(pBuf + dwLenOriginalTextByDecrypt) = '/0'; printf("解密后原文:[%s]/n", (PCHAR)pBuf); delete pBuf; getchar(); } return nRetCode; } //------------------------------------------------------------------------- // //------------------------------------------------------------------------- int nFnUkeyEncrypt(PBYTE pBufData, DWORD &dwLenBufDataToEncrypt, DWORD dwLenBuf) { CString csCspProvider = G_CS_CSP_PROVIDER; CString csCspContainer = G_CS_CSP_CONTAINER; HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; BYTE *pbData = NULL; DWORD cbData = 0; DWORD i = 0; if (!CryptAcquireContextA(&hProv, (LPSTR)(LPCSTR)csCspContainer, (LPSTR) (LPCSTR)csCspProvider, PROV_RSA_FULL, 0)) { printf("Error %x CryptAcquireContext!n", GetLastError()); _ASSERT(0); return S_FALSE; } if (!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey)) { printf("Error %x CryptGetUserKey!n", GetLastError()); CryptReleaseContext(hProv, 0); _ASSERT(0); return S_FALSE; } //用UKey自己加密解密, 不需要知道公钥信息 //加密 if (!CryptEncrypt(hKey, NULL, TRUE, 0, pBufData, &dwLenBufDataToEncrypt, dwLenBuf)) { printf("Error %x during CryptEncrypt!/n", GetLastError()); } if (hKey) { if (!CryptDestroyKey(hKey)) { printf("Error %x during CryptDestoryKey!n", GetLastError()); } } if (!CryptReleaseContext(hProv, 0)) { printf("Error %x during ReleaseContext!n", GetLastError()); } return S_OK; } //------------------------------------------------------------------------- // //------------------------------------------------------------------------- int nFnUkeyDecrypt(PBYTE pBufData, DWORD dwLenBufDataToDecrypt, DWORD &dwLenBufOrginalContent) { CString csCspProvider = G_CS_CSP_PROVIDER; CString csCspContainer = G_CS_CSP_CONTAINER; HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; BYTE *pbKeyBlob = NULL; DWORD dwBlobLen = 0; BYTE *pbData = NULL; DWORD cbData = 0; DWORD i = 0; //金邦达2006CSP驱动有BUG, 有时会在连接上下文的时候阻塞住 if (!CryptAcquireContextA(&hProv, (LPSTR)(LPCSTR)csCspContainer, (LPSTR) (LPCSTR)csCspProvider, PROV_RSA_FULL, 0)) { printf("Error %x CryptAcquireContext!n", GetLastError()); _ASSERT(0); return S_FALSE; } if (!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey)) { printf("Error %x CryptGetUserKey!n", GetLastError()); CryptReleaseContext(hProv, 0); _ASSERT(0); return S_FALSE; } //解密 dwLenBufOrginalContent = dwLenBufDataToDecrypt; if (!CryptDecrypt(hKey, NULL, TRUE, 0, pBufData, &dwLenBufOrginalContent)) { printf("Error %x during CryptDecrypt!n", GetLastError()); } if (hKey) { if (!CryptDestroyKey(hKey)) { printf("Error %x during CryptDestoryKey!/n", GetLastError()); } } if (!CryptReleaseContext(hProv, 0)) { printf("Error %x during ReleaseContext!/n", GetLastError()); } return S_OK; } int FnPrintBuffer(PCHAR pcPrefix, PBYTE pbcBuffer, DWORD dwLenBuffer) { printf("//----------------------------------------/n"); printf("//提示信息:%s/n", pcPrefix); printf("//字节流长度:%d/n", dwLenBuffer); printf("//----------------------------------------/n"); ULONG i,j,m; char buffer[0x100] = "/0"; char cBufTmp[8] = "/0"; strcpy(buffer,""); m = dwLenBuffer%16; //打印整行字符 for(i = 0; i < (dwLenBuffer -m); i++) { //格式化16进制显示部分 sprintf(cBufTmp, "%.2x", pbcBuffer[i]); _strupr(cBufTmp); strcat(buffer, cBufTmp); //每16个字符后面, 进行文本显示 if (((i + 1) % 16) == 0) { strcat(buffer, " ");//隔断(16进制显示和文本显示) for(j = (i - 15); j < (i + 1); j++) { sprintf(cBufTmp, "%c", isprint(pbcBuffer[j]) ? pbcBuffer[j] : '.' ); strcat(buffer,cBufTmp); } printf("%s/n", buffer); strcpy(buffer,""); } } if(m == 0) { return S_OK; } //打印最后一行(不满16个字符) strcpy(buffer, ""); for(i = dwLenBuffer - m; i < dwLenBuffer; i++) { sprintf(cBufTmp, "%.2x", pbcBuffer[i]); _strupr(cBufTmp); strcat(buffer, cBufTmp); } //正文补齐 for(i = 0; i < (16 - m); i++) { strcat(buffer," "); } strcat(buffer, " ");//隔断 for(j = (dwLenBuffer - m); j < dwLenBuffer; j++) { sprintf(cBufTmp, "%c", isprint(pbcBuffer[j]) ? pbcBuffer[j] : '.' ); strcat(buffer, cBufTmp); } strcat(buffer,"/n"); printf(buffer); return S_OK; }