簡體   English   中英

在C ++中使用OpenSSL將RSA密鑰格式化為公鑰

[英]Format RSA Key to Public Key with OpenSSL in C++

我有一個538個十六進制字符的RSA密鑰,如下所示:

3082010902820100C011E8900B1FFA6F4869448D4449FC57FF388B34A39C5783DE462CFD00FA6AFF30C24A579010A695EB3A0996E9417AF841874EE2A45FADBE287541BE0AC60EE40DD001220573F8EB4C0EEFEB549C16511B5FE5F2109A31BB8857C99EDAAFC8193AA8EDCE900CB31993A9CC3676CAC394105AD53A6DB2B0BE02C0A64F8103DEFA76BC9CFA256898565D545D35135D1D5D205EB99BC30DEF82DAD4664C7872372107CE28CC91AD34CE50E6C690F60B83DD4AD027C433FEDF243B710954E1A51456AA92125C3063CDCFD4E21B170F22A352F5C34350D9ADC91F0699CD5898E6BE39C0D5D58D2A3907C85B879AC8FAF98D997E2E0CDFF8ECCD3CB2354E31A582F3910203010001
  1. 我遇到的第一個問題是,我需要538個字符的密鑰來獲取其公共密鑰(根據在線程序,該公共密鑰會返回588個字符的密鑰),但我找不到如何進行轉換。 我目前正在使用該在線程序來獲取公共密鑰。

  2. 第二個問題是當我已經擁有588個字符的公共Rsa密鑰時,我需要移至以下格式:

    ----- BEGIN PUBLIC KEY ----- MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCgF35rHhOWi9 + r4n9xM / ejvMEs Q8h6lams962k4U0WSdfySUevhyI1bd3FRIb5fFqSBt6qPTiiiIw0KXte5dANB6lP e6HdUPTA / U4xHWi2FB / BfAyPsOlUBfFp6dtkEEcEKt + Z8KTJYJEerRie24y + nsfZ MnLBst6tsEBfx / U75wIBAw == ----- END PUBLIC KEY -----

目前我是通過手工將我的RSA密鑰從588個字符轉換為base64並按以下方式逐個粘貼值的:

unsigned char* publicKey;

string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) 
{
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];
    string ret;

    while (in_len--) 
    {
        char_array_3[i++] = *(bytes_to_encode++);

        if (i == 3) 
        {
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;

            for(i = 0; (i < 4) ; i++)
            {
                ret += base64_chars[char_array_4[i]];
            }

            i = 0;
        }
    }

    if (i)
    {
        for(j = i; j < 3; j++)
        {
            char_array_3[j] = '\0';
        }

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; (j < i + 1); j++)
        {
            ret += base64_chars[char_array_4[j]];
        }

        while((i++ < 3))
        {
            ret += '=';
        }
    }

    return ret;
}

bool format_to_Public_Key()
{
    string Rsa_588 = "3082010902820....10203010001"; //588 Length RSA key

    if(Rsa_588.length() == 588)
    {
        string rsa_base64 = base64_encode(reinterpret_cast<unsigned char *>(stringHex_to_charHex(Rsa_588)), (Rsa_588.length() / 2));

        string format_rsa_base64 = "-----BEGIN PUBLIC KEY-----\n" +
                                   rsa_base64.substr(0, 64) + "\n" + 
                                   rsa_base64.substr(64, 64) + "\n" +
                                   rsa_base64.substr(128, 64) + "\n" +
                                   rsa_base64.substr(192, 64) + "\n" +
                                   rsa_base64.substr(256, 64) + "\n" +
                                   rsa_base64.substr(320, 64) + "\n" +
                                   rsa_base64.substr(384, 8) + "\n" +
                                   "-----END PUBLIC KEY-----\n";

        publicKey = (unsigned char*)format_rsa_base64.c_str();

        return true;
    }

所有這些都是使用OpenSSL的RSA_public_encrypt()Api,問題是我正在“手工”做事情,我敢肯定它可以以更有效的方式完成,但我不知道是什么。 我希望您能指導我如何使用OpenSSL函數。

RSA密鑰有不同的類型和密鑰大小。 如果您指定每個,它會更有幫助。

有兩個步驟可以實現您想要的。

  1. 使用OpenSSL函數PEM_read_RSAPrivateKey將密鑰加載到OpenSSL RSA結構中。
    • 將十六進制字符粘貼到文本文件中。
    • 使用fopen將文本文件讀入帶有“ r”選項的fp中
    • 使用此功能讀取密鑰會自動將公共密鑰設置為所需的格式( PEM格式 )。
  2. 如您所說使用RSA_public_encrypt進行加密。 從上面使用RSA結構。

上面有函數的聲明。

 1. RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x,
                                    pem_password_cb *cb, void *u);
 2. int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);

假設您的密鑰是ASN.1格式的RSA密鑰對,那么您想使用d2i_RSAPrivateKey_xxx方法讀取密鑰,並使用PEM_write_bio_RSAPUBLICKey方法寫出公共密鑰。

例如

bool load_and_export_rsa_public_key()
{
    auto* bio = BIO_new_file("rsa.key", "rb");
    if(!bio) return false;
    auto const rsa = d2i_RSAPrivateKey_bio(bio, nullptr);
    BIO_free(bio);

    if(!rsa) return false;

    auto const bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
    PEM_write_bio_RSAPublicKey(bio_out, rsa);
    RSA_free(rsa);
    return true;
}

更新:如果只是RSA公鑰,則可以使用:

ASN1 RSA格式: d2i_RSAPublicKey_bio

PEM RSA格式: PEM_read_bio_RSAPublicKey

這將返回您可以使用的RSA指針。 這完全取決於您擁有RSA公鑰的格式。

暫無
暫無

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

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