c++中RSA加密和解密

//#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>


void ShowError(const char *pszText)
{
    char szErr[MAX_PATH] = { 0 };
    ::wsprintf(szErr, "%s Error[0x%x]\n", pszText, ::GetLastError());
#ifdef _DEBUG
    ::MessageBox(NULL, szErr, "ERROR", MB_OK | MB_ICONERROR);
#endif
}


// 生成公钥和私钥
BOOL GenerateKey(BYTE **ppPublicKey, DWORD *pdwPublicKeyLength, BYTE **ppPrivateKey, DWORD *pdwPrivateKeyLength)
{
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hCryptKey = NULL;
    BYTE *pPublicKey = NULL;
    DWORD dwPublicKeyLength = 0;
    BYTE *pPrivateKey = NULL;
    DWORD dwPrivateKeyLength = 0;

    do
    {
        // 获取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
        if (FALSE == bRet)
        {
            ShowError("CryptAcquireContext");
            break;
        }

        // 生成公私密钥对
        bRet = ::CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hCryptKey);
        if (FALSE == bRet)
        {
            ShowError("CryptGenKey");
            break;
        }

        // 获取公钥密钥的长度和内容
        bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLength);
        if (FALSE == bRet)
        {
            ShowError("CryptExportKey");
            break;
        }
        pPublicKey = new BYTE[dwPublicKeyLength];
        ::RtlZeroMemory(pPublicKey, dwPublicKeyLength);
        bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, pPublicKey, &dwPublicKeyLength);
        if (FALSE == bRet)
        {
            ShowError("CryptExportKey");
            break;
        }

        // 获取私钥密钥的长度和内容
        bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLength);
        if (FALSE == bRet)
        {
            ShowError("CryptExportKey");
            break;
        }
        pPrivateKey = new BYTE[dwPrivateKeyLength];
        ::RtlZeroMemory(pPrivateKey, dwPrivateKeyLength);
        bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, pPrivateKey, &dwPrivateKeyLength);
        if (FALSE == bRet)
        {
            ShowError("CryptExportKey");
            break;
        }

        // 返回数据
        *ppPublicKey = pPublicKey;
        *pdwPublicKeyLength = dwPublicKeyLength;
        *ppPrivateKey = pPrivateKey;
        *pdwPrivateKeyLength = dwPrivateKeyLength;

    }
    while (FALSE);

    // 释放关闭
    if (hCryptKey)
    {
        ::CryptDestroyKey(hCryptKey);
    }
    if (hCryptProv)
    {
        ::CryptReleaseContext(hCryptProv, 0);
    }

    return bRet;
}


// 公钥加密数据
BOOL RsaEncrypt(BYTE *pPublicKey, DWORD dwPublicKeyLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength)
{
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hCryptKey = NULL;

    do
    {
        // 获取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
        if (FALSE == bRet)
        {
            ShowError("CryptAcquireContext");
            break;
        }

        // 导入公钥
        bRet = ::CryptImportKey(hCryptProv, pPublicKey, dwPublicKeyLength, NULL, 0, &hCryptKey);
        if (FALSE == bRet)
        {
            ShowError("CryptImportKey");
            break;
        }

        // 加密数据
        bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
        if (FALSE == bRet)
        {
            ShowError("CryptImportKey");
            break;
        }

    }
    while (FALSE);

    // 释放并关闭
    if (hCryptKey)
    {
        ::CryptDestroyKey(hCryptKey);
    }
    if (hCryptProv)
    {
        ::CryptReleaseContext(hCryptProv, 0);
    }

    return bRet;
}


// 私钥解密数据
BOOL RsaDecrypt(BYTE *pPrivateKey, DWORD dwProvateKeyLength, BYTE *pData, DWORD &dwDataLength)
{
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hCryptKey = NULL;

    do
    {
        // 获取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
        if (FALSE == bRet)
        {
            ShowError("CryptAcquireContext");
            break;
        }

        // 导入私钥
        bRet = ::CryptImportKey(hCryptProv, pPrivateKey, dwProvateKeyLength, NULL, 0, &hCryptKey);
        if (FALSE == bRet)
        {
            ShowError("CryptImportKey");
            break;
        }

        // 解密数据
        bRet = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength);
        if (FALSE == bRet)
        {
            ShowError("CryptDecrypt");
            break;
        }

    }
    while (FALSE);

    // 释放并关闭
    if (hCryptKey)
    {
        ::CryptDestroyKey(hCryptKey);
    }
    if (hCryptProv)
    {
        ::CryptReleaseContext(hCryptProv, 0);
    }

    return bRet;
}



int main(int argc, char* argv[])
{
    BYTE *pPublicKey = NULL;
    DWORD dwPublicKeyLength = 0;
    BYTE *pPrivateKey = NULL;
    DWORD dwPrivateKeyLength = 0;
    BYTE *pData = NULL;
    DWORD dwDataLength = 0;
    DWORD dwBufferLength = 4096;
    DWORD i = 0;

    pData = new BYTE[dwBufferLength];
    if (NULL == pData)
    {
        return 1;
    }
    ::RtlZeroMemory(pData, dwBufferLength);
    ::lstrcpy((char *)pData, "What is your name? DemonGan");
    dwDataLength = 1 + ::lstrlen((char *)pData);
//    dwDataLength =::lstrlen((char *)pData);
    printf("Text[%ld]\n", dwDataLength);
    for (i = 0; i < dwDataLength; i++)
    {
        printf("%02x", pData[i]);
    }
    printf("\n\n");

    // 生成公钥和私钥
    GenerateKey(&pPublicKey, &dwPublicKeyLength, &pPrivateKey, &dwPrivateKeyLength);
    printf("Public Key[%ld]\n", dwPublicKeyLength);
    for (i = 0; i < dwPublicKeyLength; i++)
    {
        printf("%.2x", pPublicKey[i]);
    }
    printf("\n");
    printf("Private Key[%ld]\n", dwPrivateKeyLength);
    for (i = 0; i < dwPrivateKeyLength; i++)
    {
        printf("%.2x", pPrivateKey[i]);
    }
    printf("\n\n");

    // 公钥加密
    RsaEncrypt(pPublicKey, dwPublicKeyLength, pData, dwDataLength, dwBufferLength);
    printf("RSA Encrypt[%ld]\n", dwDataLength);
    for (i = 0; i < dwDataLength; i++)
    {
        printf("%x", pData[i]);
    }
    printf("\n\n");

    // 私钥解密
    RsaDecrypt(pPrivateKey, dwPrivateKeyLength, pData, dwDataLength);
    printf("RSA Decrypt[%ld]\n", dwDataLength);
    for (i = 0; i < dwDataLength; i++)
    {
        printf("%02x", pData[i]);
    }
    printf("\n\n");

    // 释放
    if (pData)
    {
        delete[]pData;
        pData = NULL;
    }
    if (pPrivateKey)
    {
        delete[]pPrivateKey;
        pPrivateKey = NULL;
    }
    if (pPublicKey)
    {
        delete[]pPublicKey;
        pPublicKey = NULL;
    }

//	system("pause");
    return 0;
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值