Chinaunix首页 | 论坛 | 博客
  • 博客访问: 215604
  • 博文数量: 70
  • 博客积分: 2050
  • 博客等级: 大尉
  • 技术积分: 700
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-15 21:42
文章分类

全部博文(70)

文章存档

2013年(1)

2011年(5)

2010年(3)

2009年(9)

2008年(17)

2007年(6)

2006年(29)

我的朋友

分类: WINDOWS

2008-11-26 15:23:06

#include
#include
#include
#include

#pragma comment(lib, "Crypt32.lib")

struct TestSession
{
    LPCTSTR pszContainer;
    HCRYPTPROV hProv;
    HCRYPTKEY hXKey; // 交换密钥
    HCRYPTKEY hPublicKey; // 对方公钥
    HCRYPTKEY hKey; // 会话密钥
    BYTE *pData; // 本方公钥导出
    DWORD dwLength;
};

int
sopen(LPCTSTR pszContainer, struct TestSession *s)
{
    memset(s, 0, sizeof(*s));
    s->pszContainer = pszContainer;
    if (!CryptAcquireContext(&s->hProv, s->pszContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
        if (GetLastError() == NTE_BAD_KEYSET && !CryptAcquireContext(&s->hProv, s->pszContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
            return -1;

    if (!CryptGenKey(s->hProv, CALG_RSA_KEYX, CRYPT_EXPORTABLE | (2048 << 16), &s->hXKey))
        return -1;

    if (CryptExportKey(s->hXKey, 0, PUBLICKEYBLOB, 0, NULL, &s->dwLength))
        if ((s->pData = (BYTE *)malloc(s->dwLength)) != 0)
            if (CryptExportKey(s->hXKey, 0, PUBLICKEYBLOB, 0, s->pData, &s->dwLength))
                return 0;

    return -1;
};

void
sclose(struct TestSession *s)
{
    if (s->hKey) CryptDestroyKey(s->hKey);
    if (s->hPublicKey) CryptDestroyKey(s->hPublicKey);
    if (s->hXKey) CryptDestroyKey(s->hXKey);
    if (s->pData) free(s->pData);
    if (s->hProv)
    {
        CryptAcquireContext(&s->hProv, s->pszContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
        CryptReleaseContext(s->hProv, 0);
    }
}

int
main(void)
{
    DWORD dwLength;
    BYTE *pData; // 会话密钥BLOB
    struct TestSession a, b;

    pData = 0;
    if (sopen("test.a", &a) || sopen("test.b", &b))
        printf("初始化失败!\n");
    else if (!CryptImportKey(a.hProv, b.pData, b.dwLength, 0, 0, &a.hPublicKey))
        printf("A不能导入B的公钥\n");
    else if (!CryptGenKey(a.hProv, CALG_RC4, CRYPT_EXPORTABLE, &a.hKey))
        printf("A生成会话密钥错误\n");
    else if (!CryptExportKey(a.hKey, a.hPublicKey, SIMPLEBLOB, 0, NULL, &dwLength))
        printf("A计算会话密钥长度时发生错误\n");
    else if ((pData = (BYTE *)malloc(dwLength)) == 0)
        printf("分配会话密钥时内存不够\n");
    else if (!CryptExportKey(a.hKey, a.hPublicKey, SIMPLEBLOB, 0, pData, &dwLength))
        printf("A导出会话密钥并以B的公钥加密时发生错误\n");
    else if (!CryptImportKey(b.hProv, pData, dwLength, b.hXKey, 0, &b.hKey))
        printf("B导入会话密钥错误并以自己私钥解密时发生错误\n");
    else
    {
        const char *message = "hello, foo and bar!";
        char cipher[1024], plain[1024];

        strcpy(cipher, message);
        plain[0] = '\0';
        dwLength = (DWORD)strlen(cipher) + 1;
        if (CryptEncrypt(a.hKey, 0, TRUE, 0, cipher, &dwLength, sizeof(cipher)))
        {
            memcpy(plain, cipher, dwLength);
            CryptDecrypt(b.hKey, 0, TRUE, 0, plain, &dwLength);
        }
        if (strcmp(message, plain) == 0)
            puts("test ok");
    }

    if (pData) free(pData);

    sclose(&a);
    sclose(&b);
    return 0;
}
阅读(753) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~