Как создать пару открытый / закрытый ключ для использования с OpenSSL - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь создать приложение для Windows, которое создает открытый и закрытый ключи и экспортировать его, чтобы я мог использовать его с OpenSSL.Я взял те же примеры, которые предоставляет MSDN, но что-то не так ... Я думаю, это проблема размеров для выделения памяти.

В результате мне нужен открытый и закрытый ключи в кодировке base64, например:

* * 1004 Const символ * szPemPrivKey = "----- BEGIN RSA PRIVATE KEY -----" "MIICXAIBAAKBgQCf6YAJOSBYPve1jpYDzq + ж ++ 8YVoATI / YCI / RKZaQk + l2ZfoUQ" "g0qrYrfkzeoOa / qd5VLjTTvHEgwXnlDXMfo + vSgxosUxDOZXMTBqJGOViv5K2QBv" «k8A1wi4k8tuo / 7OWya29HvcfavUk3YXaV2YFe8V6ssaZjNcVWmDdjqNkXwIDAQAB" "AoGALrd + ijNAOcebglT3ioE1XpUbUpbir7TPyAqvAZUUESF7er41jY9tnwgmBRgL" "Сз + M1dgLERCdKBkjozrDDzswifFQmq6PrmYrBkFFqCoLJwepSYdWnK1gbZ / d43rR" "2sXzSGZngscx0CxO7KZ7xUkwENGd3 + lKXV7J6 / vgzJ4XnkECQQDTP6zWKT7YDckk" "We04hbhHyBuNOW068NgUUvoZdBewerR74MJx6nz28Tp + DeNvc0EveiQxsEnbV8u +", "NRkX5y0xAkEAwcnEAGBn5kJd6SpU0ALA9XEpUv7tHTAGQYgCRbfTT59hhOq6I22A" "ivjOCNG9c6E7EB2kcPVGuCpYUhy7XBIGjwJAK5lavKCqncDKoLwGn8HJdNcyCIWv" "q5iFoDw37gTt1ricg2yx9PzmabkDz3xiUmBBNeFJkw / FToXiQRGIakyGIQJAJIem"" PPPvYgZssYFbT4LVYO8d / Rk1FWVyKHQ9CWtnmADRXz7oK7L + m7PfEuaGsf9YpOcR " "koGJ / TluQLxNzUNQnQJBAImwr / yYFenIx3HQ6UX / fCt6qpGDv0VfOLyR64MNeegx" "o7DhNxHbFkIGzk4lKhMKcHKDrawZbdJtS9ie2geSwVQ =" "----- END RSA PRIVATE KEY -----"; 1006 * Const символ * szPemPubKey =" -----BEGIN RSA ОТКРЫТОГО КЛЮЧА ----- " "MIGJAoGBAJ / pgAk5IFg + 97WOlgPOr7D77xhWgBMj9gKL9EplpCT6XZl + hRCDSqti" "T + TN6g5r + p3lUuNNO8cSDBeeUNcx + j69KDGixTEM5lcxMGokY5WK / krZAG + TwDXC" "LiTy26j / s5bJrb0e9x9q9STdhdpXZgV7xXqyxpmM1xVaYN2Oo2RfAgMBAAE ="" ----- END RSA ОБЩЕСТВЕННОЕ 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 голосов
/ 24 января 2019

похоже, вы указали неправильный формат для функции 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;
}
...