16,471
社区成员
发帖
与我相关
我的任务
分享
#//pragma comment(lib,"Crypt32.lib")
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
#define DHKEYSIZE 512
void HandleError(char *s);
static const BYTE g_rgbPrime[] =
{
0x91, 0x02, 0xc8, 0x31, 0xee, 0x36, 0x07, 0xec,
0xc2, 0x24, 0x37, 0xf8, 0xfb, 0x3d, 0x69, 0x49,
0xac, 0x7a, 0xab, 0x32, 0xac, 0xad, 0xe9, 0xc2,
0xaf, 0x0e, 0x21, 0xb7, 0xc5, 0x2f, 0x76, 0xd0,
0xe5, 0x82, 0x78, 0x0d, 0x4f, 0x32, 0xb8, 0xcb,
0xf7, 0x0c, 0x8d, 0xfb, 0x3a, 0xd8, 0xc0, 0xea,
0xcb, 0x69, 0x68, 0xb0, 0x9b, 0x75, 0x25, 0x3d,
0xaa, 0x76, 0x22, 0x49, 0x94, 0xa4, 0xf2, 0x8d
};
// Generator in little-endian format.
static BYTE g_rgbGenerator[] =
{
0x02, 0x88, 0xd7, 0xe6, 0x53, 0xaf, 0x72, 0xc5,
0x8c, 0x08, 0x4b, 0x46, 0x6f, 0x9f, 0x2e, 0xc4,
0x9c, 0x5c, 0x92, 0x21, 0x95, 0xb7, 0xe5, 0x58,
0xbf, 0xba, 0x24, 0xfa, 0xe5, 0x9d, 0xcb, 0x71,
0x2e, 0x2c, 0xce, 0x99, 0xf3, 0x10, 0xff, 0x3b,
0xcb, 0xef, 0x6c, 0x95, 0x22, 0x55, 0x9d, 0x29,
0x00, 0xb5, 0x4c, 0x5b, 0xa5, 0x63, 0x31, 0x41,
0x13, 0x0a, 0xea, 0x39, 0x78, 0x02, 0x6d, 0x62
};
//基于DH密钥交换协议的例子
void DH()
{
// PCHAR szSource;
// PCHAR szDestination;
// PCHAR szPassword;
// char response;
BYTE *bufa;
BYTE *bufb;
int buflen;
buflen = 1024 * 1024 * 10; // 10M的数据
bufa = new BYTE[buflen];
bufb = new BYTE[buflen];
memcpy(bufb, bufa, buflen);
BOOL fReturn;
HCRYPTPROV hCryptProv1 ; //密钥1的CSP
HCRYPTPROV hCryptProv2 ; //密钥2的CSP
HCRYPTKEY hPrivateKey1 = NULL;
HCRYPTKEY hPrivateKey2 = NULL;
HCRYPTKEY hSessionKey1 = NULL;
HCRYPTKEY hSessionKey2 = NULL;
DWORD dwDataLen1;
DWORD dwDataLen2;
DATA_BLOB P;
DATA_BLOB G;
PBYTE pbKeyBlob1 = NULL;
PBYTE pbKeyBlob2 = NULL;
ALG_ID Algid = CALG_DES;
BYTE *pbData;
int i = 0;
P.cbData = DHKEYSIZE/8;
P.pbData = (BYTE*)(g_rgbPrime);
G.cbData = DHKEYSIZE/8;
G.pbData = (BYTE*)(g_rgbGenerator);
printf("连接CSP1(DH)...\n");
if(CryptAcquireContext(
&hCryptProv1,
NULL,
MS_ENH_DSS_DH_PROV,//MS_ENHANCED_PROV
PROV_DSS_DH, //PROV_RSA_FULL
CRYPT_VERIFYCONTEXT)) //0
{
printf("打开CSP1成功 \n");
}
else
{
HandleError("调用 CryptAcquireContext 出错!");
}
printf("生成密钥对1...\n");
if(CryptGenKey(
hCryptProv1,
CALG_DH_EPHEM,
DHKEYSIZE << 16 | CRYPT_EXPORTABLE | CRYPT_PREGEN,
&hPrivateKey1))
{
printf("创建会话密钥1成功. \n");
}
else
{
HandleError("调用 CryptGenKey 出错!");
}
// Set the prime for party 1's private key.
fReturn = CryptSetKeyParam(
hPrivateKey1,
KP_P,
(PBYTE)&P,
0);
if(!fReturn)
{
goto ErrorExit;
}
// Set the generator for party 1's private key.
fReturn = CryptSetKeyParam(
hPrivateKey1,
KP_G,
(PBYTE)&G,
0);
if(!fReturn)
{
goto ErrorExit;
}
// Generate the secret values for party 1's private key.
fReturn = CryptSetKeyParam(
hPrivateKey1,
KP_X,
NULL,
0);
if(!fReturn)
{
goto ErrorExit;
}
printf("连接CSP2(DH)...\n");
if(CryptAcquireContext(
&hCryptProv2,
NULL,
MS_ENH_DSS_DH_PROV,//MS_ENHANCED_PROV
PROV_DSS_DH, //PROV_RSA_FULL
CRYPT_VERIFYCONTEXT)) //0
{
printf("打开CSP2成功 \n");
}
else
{
HandleError("调用 CryptAcquireContext 出错!");
}
printf("生成密钥对2...\n");
if(CryptGenKey(
hCryptProv2,
CALG_DH_EPHEM,
DHKEYSIZE << 16 | CRYPT_EXPORTABLE | CRYPT_PREGEN,
&hPrivateKey2))
{
printf("创建会话密钥2成功. \n");
}
else
{
HandleError("调用 CryptGenKey 出错!");
}
fReturn = CryptSetKeyParam(
hPrivateKey2,
KP_P,
(PBYTE)&P,
0);
if(!fReturn)
{
goto ErrorExit;
}
// Set the generator for party 2's private key.
fReturn = CryptSetKeyParam(
hPrivateKey2,
KP_G,
(PBYTE)&G,
0);
if(!fReturn)
{
goto ErrorExit;
}
// Generate the secret values for party 2's private key.
fReturn = CryptSetKeyParam(
hPrivateKey2,
KP_X,
NULL,
0);
if(!fReturn)
{
goto ErrorExit;
}
printf("\n开始导出pubkey1...\n");
//导出1的公钥
if(!CryptExportKey(hPrivateKey1,NULL,PUBLICKEYBLOB,0,NULL,&dwDataLen1))
{
goto ErrorExit;
}
if(!(pbKeyBlob1 = (PBYTE)malloc(dwDataLen1)))
{
goto ErrorExit;
}
if(!CryptExportKey(hPrivateKey1,0,PUBLICKEYBLOB,0,pbKeyBlob1,&dwDataLen1))
{
goto ErrorExit;
}
printf("成功导出pubkey1...\n");
// for(;i < dwDataLen1 ; i++)
// printf("%d ",pbKeyBlob1);
printf("\n开始导出pubkey2...\n");
//导出2的公钥
if(!CryptExportKey(hPrivateKey2,NULL,PUBLICKEYBLOB,0,NULL,&dwDataLen2))
{
goto ErrorExit;
}
if(!(pbKeyBlob2 = (PBYTE)malloc(dwDataLen2)))
{
goto ErrorExit;
}
if(!CryptExportKey(hPrivateKey2,0,PUBLICKEYBLOB,0,pbKeyBlob2,&dwDataLen2))
{
goto ErrorExit;
}
printf("成功导出pubkey2...\n");
// for(i=0;i < dwDataLen2 ; i++)
// printf("%d ",pbKeyBlob2);
printf("\n");
//party 2 导入1的公钥得到 会话密钥1
if(!CryptImportKey(
hCryptProv2,
pbKeyBlob1,
dwDataLen1,
hPrivateKey2,
0,
&hSessionKey1))
{
HandleError("调用 CryptAcquireContext 出错!");
//goto ErrorExit;
}
printf("成功得到会话密钥1...\n");
//将会话密钥1转化为对称密钥
if(!CryptSetKeyParam(hSessionKey1,KP_ALGID,(PBYTE)&Algid,0))
{
goto ErrorExit;
}
printf("成功得到对称会话密钥1...\n");
//party 1 导入2的公钥得到 会话密钥2
if(!CryptImportKey(
hCryptProv1,
pbKeyBlob2,
dwDataLen2,
hPrivateKey1,
0,
&hSessionKey2))
{
HandleError("调用 CryptAcquireContext 出错!");
goto ErrorExit;
}
printf("成功得到会话密钥2...\n");
//将会话密钥2转化为对称密钥
if(!CryptSetKeyParam(hSessionKey2,KP_ALGID,(PBYTE)&Algid,0))
{
goto ErrorExit;
}
//用会话密钥1加密一些数据
DWORD t=GetTickCount();
for(int i=0;i<10;i++)
{
DWORD dwLength=buflen-1024;
fReturn = CryptEncrypt(
hSessionKey1,
0,
TRUE,
0,
bufa,
&dwLength,
buflen);
if(!fReturn)
{
HandleError("CryptEncrypt!");
goto ErrorExit;
}
//printf("加密后:%s\n",pbData);
fReturn = fReturn = CryptDecrypt(
hSessionKey2,
0,
TRUE,
0,
bufa,
&dwLength);
if(!fReturn)
{
HandleError("CryptEncrypt!");
goto ErrorExit;
}
int datalen=buflen-1024;
if (memcmp(bufa, bufb, datalen) != 0)
HandleError("memcmp error");
//printf("使用会话密钥2解密...\n解密后:%s\n",pbData);
//用会话密钥2解密一些数据
}
printf("time: %d",GetTickCount()-t);
getchar();
ErrorExit:
if(hPrivateKey1)
{
CryptDestroyKey(hPrivateKey1);
hPrivateKey2 = NULL;
}
if(hPrivateKey2)
{
CryptDestroyKey(hPrivateKey2);
hPrivateKey2 = NULL;
}
if(hCryptProv1)
{
CryptReleaseContext(hCryptProv1, 0);
hCryptProv1 = NULL;
}
if(hCryptProv2)
{
CryptReleaseContext(hCryptProv2, 0);
hCryptProv2 = NULL;
}
}
//************************************************************************/
//出错处理函数
void HandleError(char *s)
{
printf("本程序在运行时有错误发生.\n");
printf("%s\n",s);
printf("错误码: %x\n.",GetLastError());
printf("程序退出.\n");
exit(1);
}
int main(int argc, char* argv[])
{
DH();
return 0;
}