首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何导出对称AES密钥密码AES

如何导出对称AES密钥密码AES
EN

Stack Overflow用户
提问于 2014-12-10 08:38:10
回答 1查看 3K关注 0票数 1

我有点问题。我需要生成和导出对称密钥使用CryptoAPI。

代码语言:javascript
复制
     if(CryptAcquireContext(&hCryptProv_AES, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES,  0))
    {
        _tprintf(
            TEXT("A cryptographic provider has been acquired. \n"));
    }
    else
    {
            DWORD d = GetLastError();
            std::cout<<"";
            return -1;
    }

    if (!CryptGenKey(hCryptProv_AES,CALG_AES_256,CRYPT_EXPORTABLE,&hSessionKey_AES))
        {
            DWORD d = GetLastError();
            std::cout<<"";
            return -1;
        }
    else 
    {
        std::cout<<"OK";
    }

    // Export key
   BYTE keybuf[ 1024 ], buffer[ 1024 ];
   DWORD i, keylen = sizeof( buffer );

    struct ekb
   {
       PUBLICKEYSTRUC  hdr;
       ALG_ID                 algId;
       BYTE                    key[1];
   } *encKey = (struct ekb *)buffer;

    bool bbb = CryptExportKey(hSessionKey_AES, NULL, SIMPLEBLOB, 0, (BYTE *)encKey, &keylen);
    DWORD f = GetLastError();

但不能拿走AES的钥匙。我怎样才能解决这个麻烦,请帮帮忙。我怎么能得到AES密钥??

更新,例如,我使用下一个代码,并可以获得公共RSA密钥。

代码语言:javascript
复制
char * base_txt = "Test text";
    char * enc_text = "";


     if(CryptAcquireContext(&hCryptProv_RSA, NULL, MS_ENHANCED_PROV , PROV_RSA_FULL,  0))
    {
        _tprintf(
            TEXT("A cryptographic provider has been acquired. \n"));
    }
    else
    {
            DWORD d = GetLastError();
            std::cout<<"";
            return -1;
    }

    if (!CryptGenKey(hCryptProv_RSA,AT_KEYEXCHANGE,1024<<16,&hSessionKey))
        {
            DWORD d = GetLastError();
            std::cout<<"";
            return -1;
        }

    RSAPubKey1024 key; 
    DWORD dwLen=sizeof(RSAPubKey1024);



    // Export key
    bool bb = CryptExportKey(hSessionKey,NULL,PUBLICKEYBLOB,0,(BYTE *)&key,&dwLen);

导出后的更新2我导入密钥并尝试加密和解密

代码语言:javascript
复制
HCRYPTPROV hCryptProv_AES22;
    if (CryptAcquireContext(&hCryptProv_AES22, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0))
    {
        printf("A cryptographic provider has been acquired.\r\n");
    }
    else
    {
        DWORD d = GetLastError();
        return -1;
    }
    int iii =  CryptImportKey(hCryptProv_AES22,(BYTE *)&exportKey_AES,keylen,NULL,NULL,&hSessionKey_AES2);

    if(CryptSetKeyParam(hSessionKey_AES2,KP_IV, exportKey_AES, 0))
    {
        BYTE encryptedMessage[1024];
        const char * message = "Decryption Works -- using multiple blocks";
        BYTE messageLen = (BYTE)strlen(message);
        memcpy(encryptedMessage, message, messageLen);
        DWORD encryptedMessageLen = messageLen;
        CryptEncrypt(hSessionKey_AES2, NULL, TRUE, 0, encryptedMessage, &encryptedMessageLen, sizeof(encryptedMessage));    
        CryptDecrypt(hSessionKey_AES2,NULL,TRUE,0,encryptedMessage, &encryptedMessageLen);

    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-10 09:13:54

CryptExportKey有一个限制。要求以加密的形式导出非公钥.当您导出公共部分或RSA密钥对时,可以制作第二个CryptExportKey参数NULL并以未加密的形式导出密钥。但是,您不能对对称密钥执行必须指定非空hExpKey参数的相同操作。如果指定hExpKey参数,则代码工作,请参见示例:

代码语言:javascript
复制
#include <Windows.h>
#include <cstdio>

int main(int argc, char *argv[])
{
    // Create AES key
    HCRYPTPROV hCryptProv_AES;
    if (CryptAcquireContext(&hCryptProv_AES, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0))
    {
        printf("A cryptographic provider has been acquired.\r\n");
    }
    else
    {
        DWORD d = GetLastError();
        return -1;
    }
    HCRYPTKEY hSessionKey_AES;
    if (!CryptGenKey(hCryptProv_AES, CALG_AES_256, CRYPT_EXPORTABLE, &hSessionKey_AES))
    {
        DWORD d = GetLastError();
        return -1;
    }
    // Create RSA key to encrypt AES one
    HCRYPTKEY hSessionKey;
    if (!CryptGenKey(hCryptProv_AES, AT_KEYEXCHANGE, 1024 << 16, &hSessionKey))
    {
        DWORD d = GetLastError();
        return -1;
    }
    // Export key
    DWORD keylen;
    BOOL ok = CryptExportKey(hSessionKey_AES, hSessionKey, SIMPLEBLOB, 0, NULL, &keylen);
    if (ok == FALSE)
    {
        DWORD d = GetLastError();
        return -1;
    }
    BYTE *encKey = (BYTE *)malloc(keylen);
    ok = CryptExportKey(hSessionKey_AES, hSessionKey, SIMPLEBLOB, 0, encKey, &keylen);
    if (ok == FALSE)
    {
        DWORD d = GetLastError();
        return -1;
    }
    else
        printf("A cryptographic key export succeeded.\r\n");
    return 0;
}

如果您想要进行密钥交换(例如,如果您希望Alice发送给Bob她的AES密钥),您必须执行以下步骤:

  1. Bob生成RSA密钥并将其公共部分发送给Alice。看,鲍勃开始了,不是爱丽丝!
  2. 鲍勃把他的关键公开部分交给爱丽丝。
  3. 爱丽丝生成AES密钥。
  4. Alice用Bob的公钥加密AES密钥。
  5. 爱丽丝把AES密钥发给鲍勃。
  6. Bob使用他的私钥解密AES密钥(即用CryptImportKey导入它)。导入密钥时,将hPubKey参数设置为非空值,实际上将其设置为Bob的密钥句柄,否则导入将失败,因为加密的AES密钥。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27396474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档