如何创建用于OpenSSL的公钥/私钥对

时间:2019-01-24 18:16:39

标签: c++ key private public cryptoapi

我正在尝试创建一个Windows应用程序,该应用程序将创建一个公钥和私钥并将其导出,以便可以与OpenSSL一起使用。 我采用了MSDN提供的相同示例,但是出了点问题...我认为这是分配内存大小的问题。

我需要的结果是这样的base64编码的公钥和私钥:

const char * szPemPrivKey =     “ ----- BEGIN RSA私钥-----”     “ MIICXAIBAAKBgQCf6YAJOSBYPve1jpYDzq + w ++ 8YVoATI / YCi / RKZaQk + l2ZfoUQ”     “ g0qrYrfkzeoOa / qd5VLjTTvHEgwXnlDXMfo + vSgxosUxDOZXMTBqJGOViv5K2QBv”     “ k8A1wi4k8tuo / 7OWya29HvcfavUk3YXaV2YFe8V6ssaZjNcVWmDdjqNkXwIDAQAB”     “ AoGALrd + ijNAOcebglT3ioE1XpUbUpbir7TPyAqvAZUUESF7er41jY9tnwgmBRgL”     “ Cs + M1dgLERCdKBkjozrDDzswifFQmq6PrmYrBkFFqCoLJwepSYdWnK1gbZ / d43rR”     “ 2sXzSGZngscx0CxO7KZ7xUkwENGd3 + lKXV7J6 / vgzJ4XnkECQQDTP6zWKT7YDckk”     “ We04hbhHyBuNOW068NgUUvoZdBewerR74MJx6nz28Tp + DeNvc0EveiQxsEnbV8u +”     “ NRkX5y0xAkEAwcnEAGBn5kJd6SpU0ALA9XEpUv7tHTAGQYgCRbfTT59hhOq6I22A”     “ ivjOCNG9c6E7EB2kcPVGuCpYUhy7XBIGjwJAK5lavKCqncDKoLwGn8HJdNcyCIWv”     “ q5iFoDw37gTt1ricg2yx9PzmabkDz3xiUmBBNeFJkw / FToXiQRGIakyGIQJAJIem”     “ PPPvYgZssYFbT4LVYO8d / Rk1FWVyKHQ9CWtnmADRXz7oK7l + m7PfEuaGsf9YpOcR”     “ koGJ / TluQLxNzUNQnQJBAImwr / yYFenIx3HQ6UX / fCt6qpGDv0VfOLyR64MNeegx”     “ o7DhNxHbFkIGzk4lKhMKcHKDrawZbdJtS9ie2geSwVQ =”     “ ----- END RSA PRIVATE KEY -----”;

const char * szPemPubKey =     “ ----- BEGIN RSA公钥-----”     “ MIGJAoGBAJ / pgAk5IFg + 97WOlgPOr7D77xhWgBMj9gKL9EplpCT6XZl + hRCDSqti”     “ t + TN6g5r + p3lUuNNO8cSDBeeUNcx + j69KDGixixTEM5lcxMGokY5WK / krZAG + TwDXC”     “ LiTy26j / s5bJrb0e9x9q9STdhdpXZgV7xXqyxpmM1xVaYN2Oo2RfAgMBAAE =”     “ ----- END RSA PUBLIC KEY -----”;

https://www.idrix.fr/Root/Samples/capi_pem.cpp

有人可以更正我的代码或给我提示我做错了什么吗?

int CreateKeys(DWORD keyLength)
{
/* variables */
HCRYPTPROV hCryptProv = NULL;
DWORD flags = keyLength /*key length*/ << 16;
flags |= CRYPT_EXPORTABLE;
DWORD size = 0;
HCRYPTKEY hKey = NULL;

/* variables public key */
HCRYPTKEY hPublicKey = NULL;
DWORD dwPublicKeyLen = 0;
BYTE* pbPublicKey = NULL;
HANDLE hPublicKeyFile = NULL;
LPBYTE pPublicBLOB = (LPBYTE)LocalAlloc(0, size);

/* variables private key */
HCRYPTKEY hPrivateKey = NULL;
DWORD dwPrivateKeyLen = 0;
BYTE* pbPrivateKey = NULL;
HANDLE hPrivateKeyFile = NULL;
LPBYTE pPrivateKeyBLOB = (LPBYTE)LocalAlloc(0, size);

/* get provider */  
DWORD rc = CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);

// Generate new key pair
//_tprintf(_T("CryptGenKey...\n"));
if (!CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_ARCHIVABLE, &hKey))
{
    // Error
    //_tprintf(_T("CryptGenKey error 0x%x\n"), GetLastError());
    return 1;
}
// Get public key size
//_tprintf(_T("CryptExportKey...\n"));
if (!CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLen))
{
    // Error
    //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
    return 1;
}
// Create a buffer for the public key
//_tprintf(_T("malloc...\n"));
if (!(pbPublicKey = (BYTE *)malloc(dwPublicKeyLen)))
{
    // Error
    //_tprintf(_T("malloc error 0x%x\n"), GetLastError());
    return 1;
}
// Get public key
//_tprintf(_T("CryptExportKey...\n"));
if (!CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbPublicKey, &dwPublicKeyLen))
{
    // Error
    //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
    return 1;
}





// Get private key size
//_tprintf(_T("CryptExportKey...\n"));
if (!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLen))
{
    // Error
    //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
    return 1;
}
// Create a buffer for the private key
//_tprintf(_T("malloc...\n"));
if (!(pbPrivateKey = (BYTE *)malloc(dwPrivateKeyLen)))
{
    // Error
    //_tprintf(_T("malloc error 0x%x\n"), GetLastError());
    return 1;
}
// Get private key
//_tprintf(_T("CryptExportKey...\n"));
if (!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbPrivateKey, &dwPrivateKeyLen))
{
    // Error
    //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
    return 1;
}

/*
rc = CryptExportKey(hPrivateKey, 0, PRIVATEKEYBLOB, 0, 0, &size);
LPBYTE pPrivKeyBLOB = (LPBYTE)LocalAlloc(0, size);
rc = CryptExportKey(hPrivateKey, 0, PRIVATEKEYBLOB, 0, pPrivKeyBLOB, &size);
*/

/* DER */
rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbPrivateKey, 0, NULL, NULL, &dwPrivateKeyLen);

LPBYTE pPrivateDER = (LPBYTE)LocalAlloc(0, dwPrivateKeyLen);
rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbPrivateKey, 0, NULL, pPrivateDER, &dwPrivateKeyLen);

/* PEM */
DWORD pemPrivateSize = 0;
rc = CryptBinaryToStringA(pPrivateDER, dwPrivateKeyLen, CRYPT_STRING_BASE64HEADER, NULL, &pemPrivateSize);

LPSTR pPrivatePEM = (LPSTR)LocalAlloc(0, pemPrivateSize);
rc = CryptBinaryToStringA(pPrivateDER, dwPrivateKeyLen, CRYPT_STRING_BASE64HEADER, pPrivatePEM, &pemPrivateSize);



/* DER */
rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, pbPublicKey, 0, NULL, NULL, &dwPublicKeyLen);

LPBYTE pPublicDER = (LPBYTE)LocalAlloc(0, dwPublicKeyLen);
rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, pbPublicKey, 0, NULL, pPublicDER, &dwPublicKeyLen);

/* PEM */
DWORD pemPublicSize = 0;
rc = CryptBinaryToStringA(pPublicDER, dwPublicKeyLen, CRYPT_STRING_BASE64HEADER, NULL, &pemPublicSize);

LPSTR pPublicPEM = (LPSTR)LocalAlloc(0, pemPublicSize);
rc = CryptBinaryToStringA(pPublicDER, dwPublicKeyLen, CRYPT_STRING_BASE64HEADER, pPrivatePEM, &pemPublicSize);

printf("%s", pPrivatePEM);
printf("%s", pPublicPEM);

return 0;
}

1 个答案:

答案 0 :(得分:0)

似乎您为CryptEncodeObjectEx函数提供了错误的格式以获取公共密钥 我使用CryptExportPublicKeyInfo来获取正确的键信息。

尝试以下代码:

int CreateKeys(DWORD keyLength)
{
    /* variables */
    HCRYPTPROV hCryptProv = NULL;
    DWORD flags = keyLength /*key length*/ << 16;
    flags |= CRYPT_EXPORTABLE;
    DWORD size = 0;
    HCRYPTKEY hKey = NULL;

    /* variables public key */
    HCRYPTKEY hPublicKey = NULL;
    DWORD dwPublicKeyLen = 0;
    BYTE* pbPublicKey = NULL;
    HANDLE hPublicKeyFile = NULL;
    LPBYTE pPublicBLOB = (LPBYTE)LocalAlloc(0, size);

    /* variables private key */
    HCRYPTKEY hPrivateKey = NULL;
    DWORD dwPrivateKeyLen = 0;
    BYTE* pbPrivateKey = NULL;
    HANDLE hPrivateKeyFile = NULL;
    LPBYTE pPrivateKeyBLOB = (LPBYTE)LocalAlloc(0, size);

    /* get provider */
    DWORD rc = CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);

    // Generate new key pair
    //_tprintf(_T("CryptGenKey...\n"));
    if (!CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_ARCHIVABLE, &hKey)) {
        // Error
        //_tprintf(_T("CryptGenKey error 0x%x\n"), GetLastError());
        return 1;
    }
    // Get public key size
    //_tprintf(_T("CryptExportKey...\n"));
    if (!CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLen)) {
        // Error
        //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
        return 1;
    }
    // Create a buffer for the public key
    //_tprintf(_T("malloc...\n"));
    if (!(pbPublicKey = (BYTE *)malloc(dwPublicKeyLen))) {
        // Error
        //_tprintf(_T("malloc error 0x%x\n"), GetLastError());
        return 1;
    }
    // Get public key
    //_tprintf(_T("CryptExportKey...\n"));
    if (!CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbPublicKey, &dwPublicKeyLen)) {
        // Error
        //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
        return 1;
    }





    // Get private key size
    //_tprintf(_T("CryptExportKey...\n"));
    if (!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLen)) {
        // Error
        //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
        return 1;
    }
    // Create a buffer for the private key
    //_tprintf(_T("malloc...\n"));
    if (!(pbPrivateKey = (BYTE *)malloc(dwPrivateKeyLen))) {
        // Error
        //_tprintf(_T("malloc error 0x%x\n"), GetLastError());
        return 1;
    }
    // Get private key
    //_tprintf(_T("CryptExportKey...\n"));
    if (!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbPrivateKey, &dwPrivateKeyLen)) {
        // Error
        //_tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
        return 1;
    }

    /*
    rc = CryptExportKey(hPrivateKey, 0, PRIVATEKEYBLOB, 0, 0, &size);
    LPBYTE pPrivKeyBLOB = (LPBYTE)LocalAlloc(0, size);
    rc = CryptExportKey(hPrivateKey, 0, PRIVATEKEYBLOB, 0, pPrivKeyBLOB, &size);
    */

    /* DER */
    rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbPrivateKey, 0, NULL, NULL, &dwPrivateKeyLen);

    LPBYTE pPrivateDER = (LPBYTE)LocalAlloc(0, dwPrivateKeyLen);
    rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbPrivateKey, 0, NULL, pPrivateDER, &dwPrivateKeyLen);

    /* PEM */
    DWORD pemPrivateSize = 0;
    rc = CryptBinaryToStringA(pPrivateDER, dwPrivateKeyLen, CRYPT_STRING_BASE64HEADER, NULL, &pemPrivateSize);

    LPSTR pPrivatePEM = (LPSTR)LocalAlloc(0, pemPrivateSize);
    rc = CryptBinaryToStringA(pPrivateDER, dwPrivateKeyLen, CRYPT_STRING_BASE64HEADER, pPrivatePEM, &pemPrivateSize);

    DWORD  pkiLen = 0;
    LPVOID pki = nullptr;
    rc = CryptExportPublicKeyInfo(hCryptProv, AT_KEYEXCHANGE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, &pkiLen);

    // allocate memory
    pki = (LPBYTE)LocalAlloc(0, pkiLen);

    rc = CryptExportPublicKeyInfo(hCryptProv, AT_KEYEXCHANGE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (PCERT_PUBLIC_KEY_INFO)pki, &pkiLen);

    /* DER */   
    rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, pki, 0, NULL, NULL, &pkiLen);

    LPBYTE pPublicDER = (LPBYTE)LocalAlloc(0, dwPublicKeyLen);
    rc = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, pki, 0, NULL, pPublicDER, &dwPublicKeyLen);

    /* PEM */
    DWORD pemPublicSize = 0;
    rc = CryptBinaryToStringA(pPublicDER, dwPublicKeyLen, CRYPT_STRING_BASE64HEADER, NULL, &pemPublicSize);

    LPSTR pPublicPEM = (LPSTR)LocalAlloc(0, pemPublicSize);
    rc = CryptBinaryToStringA(pPublicDER, dwPublicKeyLen, CRYPT_STRING_BASE64HEADER, pPublicPEM, &pemPublicSize);

    printf("%s", pPrivatePEM);
    printf("%s", pPublicPEM);

    return 0;
}