簡體   English   中英

如何在 C/C++ 中獲取 RSA 公鑰模數和指數?

[英]How to fetch RSA public key modulus and exponent in C/C++?

我正在使用BCrypt Windows 庫來處理我的應用程序中的 RSA 算法。

問題:我需要獲取 RSA公鑰模數和指數

在 C# 語言中,我使用 RSACryptoProvider class 來獲取這些信息(ExportParameters 方法)。

在我的 C/C++ 應用程序中,BCrypt 似乎無法獲取正確的數據......

到目前為止我所做的:

BOOL RSA_New(RSA_CTX_ST* rsa_ctx, const BYTE key_data[256], DWORD key_len, BOOL cipher)
{
    if (rsa_ctx == NULL || key_len != RSA_2048_BLOCK_SIZE)
    {
        return FALSE;
    }

    NTSTATUS status = STATUS_UNSUCCESSFUL;
    BCRYPT_ALG_HANDLE* algo_handle = NULL;
    BCRYPT_KEY_HANDLE* key_handle = NULL;

    algo_handle = malloc(sizeof(BCRYPT_ALG_HANDLE));
    key_handle = malloc(sizeof(BCRYPT_KEY_HANDLE));

    if (algo_handle == NULL || key_handle == NULL) goto END;

    //Creation handle Algo
    if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(algo_handle, BCRYPT_RSA_ALGORITHM, NULL, 0)))
    {
        UTL_Trace("SEC", VRB_MAJOR, "RSA:Algorithm handle opening error");
        if (status == STATUS_INVALID_HANDLE)
        {
            UTL_Trace("SEC", VRB_INFO, "INVALID HANDLE");
        }
        if (status == STATUS_INVALID_PARAMETER)
        {
            UTL_Trace("SEC", VRB_INFO, "INVALID PARAMS");
        }
        goto END;
    }

    // Key pair generation
    if (!NT_SUCCESS(status = BCryptGenerateKeyPair(algo_handle, key_handle, 2048, 0)))
    {
        UTL_Trace("SEC", VRB_MAJOR, "RSA:Key pair generating error");
        if (status == STATUS_INVALID_HANDLE)
        {
            UTL_Trace("SEC", VRB_INFO, "INVALID HANDLE");
        }
        if (status == STATUS_INVALID_PARAMETER)
        {
            UTL_Trace("SEC", VRB_INFO, "INVALID PARAMS");
        }
        goto END;
    }

    BCRYPT_RSAKEY_BLOB my_rsa_blob;
    ULONG* pcbResult = NULL;
    pcbResult = calloc(1, sizeof(ULONG));
    if (pcbResult == NULL)
    {
        UTL_Trace("SEC", VRB_INFO, "Allocating RSA result error");
        goto END;
    }

    // Export parameters of keys
    if (!NT_SUCCESS(status = BCryptExportKey(key_handle, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, &my_rsa_blob, sizeof(my_rsa_blob), pcbResult, 0)))
    {
        UTL_Trace("SEC", VRB_MAJOR, "RSA:Key pair exporting error");
        if (status == STATUS_INVALID_HANDLE)
        {
            UTL_Trace("SEC", VRB_INFO, "INVALID HANDLE");
        }
        if (status == STATUS_INVALID_PARAMETER)
        {
            UTL_Trace("SEC", VRB_INFO, "INVALID PARAMS");
        }
        goto END;
    }
    return TRUE;

END:
    if (algo_handle != NULL) free(algo_handle);
    if (key_handle != NULL) free(key_handle);

    return FALSE;
}

在 my_rsa_blob 中,我應該有模數和指數的大小,但不是它們的值......

有沒有人可以解決這個問題?

事實上,我確實找到了解決方案!

通過調用BCryptExportKey ,變量 my_rsa_blob 應該是一個 PUCHAR 變量,它是一個指向字符串的指針。

有了這個,我在搜索時在 Microsoft Docs 中找到了一個鏈接......該鏈接顯示了 PUCHAR 變量的設計方式:

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/540b7b8b-2232-45c8-9d7c-af7a5d5218ed

之后,您可以嘗試像這樣操作數據:

static BOOL RSA_RecoverKeyInformation(RSA_CTX_ST* rsa_ctx, PUCHAR ptrKey)
{
    strncpy(rsa_ctx->key_information.header.Magic, ptrKey[0], 4);
    strncpy(rsa_ctx->key_information.header.BitLength, ptrKey[1 * 4], 4);
    strncpy(rsa_ctx->key_information.header.cbPublicExp, ptrKey[2 * 4], 4);
    strncpy(rsa_ctx->key_information.header.cbModulus, ptrKey[3 * 4], 4);
    strncpy(rsa_ctx->key_information.header.cbPrime1, ptrKey[4 * 4], 4);
    strncpy(rsa_ctx->key_information.header.cbPrime2, ptrKey[5 * 4], 4);

    size_t sizeOfModulus = rsa_ctx->key_information.header.cbModulus;
    size_t sizeOfExponent = rsa_ctx->key_information.header.cbPublicExp;

    rsa_ctx->key_information.keyExponent = malloc(sizeOfExponent);
    rsa_ctx->key_information.keyModulus = malloc(sizeOfModulus);
    if (rsa_ctx->key_information.keyExponent == NULL || rsa_ctx->key_information.keyModulus == NULL) goto END;

    strncpy(rsa_ctx->key_information.keyExponent, ptrKey[6 * 4], sizeOfExponent);
    strncpy(rsa_ctx->key_information.keyModulus, ptrKey[6 * 4 + sizeOfExponent], sizeOfModulus);

    return TRUE;

END:
    if (rsa_ctx->key_information.keyExponent != NULL) free(rsa_ctx->key_information.keyExponent);
    if (rsa_ctx->key_information.keyModulus != NULL) free(rsa_ctx->key_information.keyModulus);
    return FALSE;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM