首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >生成RSA-2048密钥(公钥和私钥)

生成RSA-2048密钥(公钥和私钥)
EN

Stack Overflow用户
提问于 2019-06-04 17:19:51
回答 1查看 474关注 0票数 1

我正在做一个简单的实现RSA-2048。我在另一个论坛上找到了一些代码。

代码语言:javascript
运行
复制
#include <string>
#include <iostream>
#include <windows.h>
#include <Wincrypt.h>

using namespace std;

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

BYTE* Crypt(const string& _str, DWORD* _outLength);

BYTE* Decrypt(BYTE* _encryptedData, DWORD* _length);

const char* szPemPrivKey =
"-----BEGIN RSA PRIVATE KEY-----"
"MIICWwIBAAKBgQCn7fL/1qsWkJkUtXKZIJNqYfnVByVhK/LzQecPhVR7r+4ng1nZ"
"Bxg44SexS63iYlnodqDWkH/Hi82Uc0UmugY/Ow39uEGeoiYqWl5BLM8pfRAGqzxb"
"h600Qd/Oc5kYdg8hP0D/gAHXwutL74fygpB6xb8EZl2BHKvpDR80GYFlrQIDAQAB"
"AoGAZ4ZHsfTTEFwgIyYg+cmdV44DCJMZNihz5AcSvPzDMmUo+m79as/23MnhQGmZ"
"TuC28JqBWQVH4OqM2CGf1doEkuLZ/rcgxDipRqbLkEW3T/q+kJ2m9A652ePbHUKX"
"ayozDQrWtL4wkvAQQ9Il6vx+AJUzT41hv1PKZ5KWxONiJDkCQQDRsObUVVc6exb+"
"YUWVgN0pivHudKIwGUN3js09MjHoen9LbUcvupO3seAUhnNQ17t+1XxsrnPKabQQ"
"OimcPK3XAkEAzQQEI++NdoLYJv1oKYADzOUbDAmfoZ/szN6z//53h8zt5ni+6Q0n"
"k7nyrVXWuLeP0rEvD0hMOzI0mfUMwbtwGwJAMUYId8y1+qAB/zSMTV1CmwhzYT02"
"/2ZwXB/KSp8I60AduXOsTqLhI0FBDpGpd026WUuBOWik/ONp1IZWUMhRcQJAHI+U"
"rBTxVjNAPZ5L5owo+2BndjPZA0EuUhQsa1td95M7CUKFBh6JBvF+t1sgALfB145L"
"igt+YzjJTzFuR4b/RQJATgZuFyBiuLHrMES2vAtmLRlF6uTzsrNZLLUko2Rfzkzh"
"qR4inQOWWZLFzjqp3ha9rzCSVY+nBw+xD+B9hBlsNw=="
"-----END RSA PRIVATE KEY-----";

const char* szPemPublicKey =
"-----BEGIN PUBLIC KEY-----"
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn7fL/1qsWkJkUtXKZIJNqYfnV"
"ByVhK/LzQecPhVR7r+4ng1nZBxg44SexS63iYlnodqDWkH/Hi82Uc0UmugY/Ow39"
"uEGeoiYqWl5BLM8pfRAGqzxbh600Qd/Oc5kYdg8hP0D/gAHXwutL74fygpB6xb8E"
"Zl2BHKvpDR80GYFlrQIDAQAB"
"-----END PUBLIC KEY-----";


int main()
{
    string str_data = "test RSA implementation";

    DWORD encryptedDataLen;
    BYTE* encrytedData = Crypt(str_data, &encryptedDataLen);
    cout << encrytedData << endl;

    cout << endl;

    BYTE* decryptedData = Decrypt(encrytedData, &encryptedDataLen);
    cout << decryptedData << endl;

    delete(encrytedData);
    delete(decryptedData);

    return 0;
}

BYTE* Crypt(const string& _str, DWORD* _outLength)
{
    char            pemPubKey[2048];
    memcpy((void*)pemPubKey, szPemPublicKey, strlen(szPemPublicKey));
    char            derPubKey[2048];
    DWORD           derPubKeyLen = 2048;
    CERT_PUBLIC_KEY_INFO* publicKeyInfo;
    DWORD           publicKeyInfoLen;
    HANDLE          hFile;
    HCRYPTPROV      hProv = 0;
    HCRYPTKEY       hKey = 0;


    // Convert from PEM format to DER format - removes header and footer and decodes from base64
    if (!CryptStringToBinaryA(pemPubKey, 0, CRYPT_STRING_BASE64HEADER, (BYTE*)derPubKey, &derPubKeyLen, NULL, NULL))
    {
        fprintf(stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError());
        return NULL;
    }

    // Decode from DER format to CERT_PUBLIC_KEY_INFO    
    if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, (BYTE*)derPubKey, derPubKeyLen,
        CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen))
    {
        fprintf(stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError());
        return NULL;
    }

    if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
    {
        {
            printf("CryptAcquireContext failed - err=0x%x.\n", GetLastError());
            return NULL;
        }
    }

    if (!CryptImportPublicKeyInfo(hProv, X509_ASN_ENCODING, publicKeyInfo, &hKey))
    {
        fprintf(stderr, "CryptImportPublicKeyInfo failed. error: %d\n", GetLastError());
        return NULL;
    }
    // LocalFree( publicKeyInfo );


    // get size of buffer
    DWORD strLen = _str.length() * sizeof(char);
    DWORD bufLen = strLen;
    if (!CryptEncrypt(hKey, 0, true, 0, 0, &bufLen, strLen))
    {
        cout << "CryptEncrypt() failed with error " << GetLastError() << endl;
        return NULL;
    }
    // Crypt string data
    BYTE* cipherBlock = new BYTE[bufLen];
    memset((void*)cipherBlock, 0, bufLen);
    memcpy((void*)cipherBlock, _str.c_str(), strLen);
    if (!CryptEncrypt(hKey, 0, TRUE, 0, cipherBlock, &strLen, bufLen))
    {
        cout << "CryptEncrypt() failed with error " << GetLastError() << endl;
        return NULL;
    }

    *_outLength = bufLen;
    return cipherBlock;
}

BYTE* Decrypt(BYTE* _encryptedData, DWORD* _length)
{
    DWORD dwBufferLen = 0, cbKeyBlob = 0, cbSignature = 0/*,i*/;
    LPBYTE pbBuffer = NULL, pbKeyBlob = NULL, pbSignature = NULL;
    HCRYPTPROV hProv = NULL;
    HCRYPTKEY hKey = NULL;
    HCRYPTHASH hHash = NULL;

    if (!CryptStringToBinaryA(szPemPrivKey, 0, CRYPT_STRING_BASE64HEADER, NULL, &dwBufferLen, NULL, NULL))
    {
        cout << "Failed to convert BASE64 private key. Error " << GetLastError() << endl;
        return NULL;
    }

    pbBuffer = (LPBYTE)LocalAlloc(0, dwBufferLen);
    if (!CryptStringToBinaryA(szPemPrivKey, 0, CRYPT_STRING_BASE64HEADER, pbBuffer, &dwBufferLen, NULL, NULL))
    {
        cout << "Failed to convert BASE64 private key. Error " << GetLastError() << endl;
        return NULL;
    }

    if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, NULL, NULL, &cbKeyBlob))
    {
        cout << "Failed to parse private key. Error " << GetLastError() << endl;
        return NULL;
    }

    pbKeyBlob = (LPBYTE)LocalAlloc(0, cbKeyBlob);
    if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, NULL, pbKeyBlob, &cbKeyBlob))
    {
        cout << "Failed to parse private key. Error " << GetLastError() << endl;
        return NULL;
    }

    if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0))
    {
        if (GetLastError() == NTE_BAD_KEYSET)
        {
            if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
            {
                cout << "CryptAcquireContext() failed with error " << GetLastError() << endl;
                return NULL;
            }
        }
        else
        {
            cout << "CryptAcquireContext() failed with error " << GetLastError() << endl;
            return NULL;
        }
    }

    if (!CryptImportKey(hProv, pbKeyBlob, cbKeyBlob, NULL, 0, &hKey))
    {
        cout << "CryptImportKey() failed with error " << GetLastError() << endl;
        return NULL;
    }


    // Decrypt
    DWORD bufLen = *_length + 1;
    BYTE* cipherBlock = new BYTE[bufLen];
    memset((void*)cipherBlock, 0, bufLen);
    memcpy((void*)cipherBlock, _encryptedData, *_length);
    if (!CryptDecrypt(hKey, 0, TRUE, 0, cipherBlock, _length))
    {
        cout << "CryptDecrypt() failed with error " << GetLastError() << endl;
        return NULL;
    }

    // Decrypted data
    BYTE* decryptedData = new BYTE[*_length + 1];
    decryptedData[*_length] = 0;
    memcpy((void*)decryptedData, cipherBlock, *_length);

    delete(cipherBlock);
    if (pbBuffer) LocalFree(pbBuffer);
    if (pbKeyBlob) LocalFree(pbKeyBlob);
    if (pbSignature) LocalFree(pbSignature);
    if (hHash) CryptDestroyHash(hHash);
    if (hKey) CryptDestroyKey(hKey);
    if (hProv) CryptReleaseContext(hProv, 0);

    return decryptedData;
}

因此,加密\解密工作得很好。我要换钥匙。如何为这段代码生成密钥?

我试过这个在线生成器,但它不工作。https://travistidwell.com/jsencrypt/demo/和其他在线生成器

EN

回答 1

Stack Overflow用户

发布于 2019-06-04 23:40:12

NCryptCreatePersistedKey 。请放弃旧的Crypt*函数,转而使用NCrypt和BCrypt*变体。如果您坚持使用旧的API,请使用this

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56440993

复制
相关文章

相似问题

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